OAuth 2.0 Auth Middleware¶
Daml Connect includes an implementation of an auth middleware that supports OAuth 2.0 Authorization Code Grant. The implementation aims to be configurable to support different OAuth 2.0 providers and to allow custom mappings from Daml ledger claims to OAuth 2.0 scopes.
OAuth 2.0 Configuration¶
RFC 6749 specifies that OAuth 2.0 providers offer two endpoints: The authorization endpoint and the token endpoint. The URIs for these endpoints can be configured independently using the following flags:
--oauth-auth
--oauth-token
The OAuth 2.0 provider may require that the application identify itself using a client identifier and client secret. These can be specified using the following environment variables:
DAML_CLIENT_ID
DAML_CLIENT_SECRET
The auth middleware assumes that the OAuth 2.0 provider issues JWT access tokens.
The /auth
endpoint will validate the token, if available, and ensure that it grants the requested claims.
The auth middleware accepts the same command-line flags as the Daml Sandbox to define the public key for token validation.
Request Templates¶
The exact format of OAuth 2.0 requests may vary between providers. Furthermore, the mapping from Daml ledger claims to OAuth 2.0 scopes is defined by the IAM operator. For that reason OAuth 2.0 requests made by auth middleware can be configured using user defined Jsonnet templates. Templates are parameterized configurations expressed as top-level functions.
Authorization Request¶
This template defines the format of the Authorization request. Use the following command-line flag to use a custom template:
--oauth-auth-template
Arguments¶
The template will be passed the following arguments:
config
(object)clientId
(string) the OAuth 2.0 client identifierclientSecret
(string) the OAuth 2.0 client secret
request
(object)claims
(object) the requested claimsadmin
(bool)applicationId
(string or null)actAs
(list of string)readAs
(list of string)
redirectUri
(string)state
(string)
Returns¶
The query parameters for the authorization endpoint encoded as an object with string values.
Example¶
local scope(claims) =
local admin = if claims.admin then "admin";
local applicationId = if claims.applicationId != null then "applicationId:" + claims.applicationId;
local actAs = std.map(function(p) "actAs:" + p, claims.actAs);
local readAs = std.map(function(p) "readAs:" + p, claims.readAs);
[admin, applicationId] + actAs + readAs;
function(config, request) {
"audience": "https://daml.com/ledger-api",
"client_id": config.clientId,
"redirect_uri": request.redirectUri,
"response_type": "code",
"scope": std.join(" ", ["offline_access"] + scope(request.claims)),
"state": request.state,
}
Token Request¶
This template defines the format of the Token request. Use the following command-line flag to use a custom template:
--oauth-token-template
Arguments¶
The template will be passed the following arguments:
config
(object)clientId
(string) the OAuth 2.0 client identifierclientSecret
(string) the OAuth 2.0 client secret
request
(object)code
(string)redirectUri
(string)
Returns¶
The request parameters for the token endpoint encoded as an object with string values.
Example¶
function(config, request) {
"client_id": config.clientId,
"client_secret": config.clientSecret,
"code": request.code,
"grant_type": "authorization_code",
"redirect_uri": request.redirectUri,
}
Refresh Request¶
This template defines the format of the Refresh request. Use the following command-line flag to use a custom template:
--oauth-refresh-template
Arguments¶
The template will be passed the following arguments:
config
(object)clientId
(string) the OAuth 2.0 client identifierclientSecret
(string) the OAuth 2.0 client secret
request
(object)refreshToken
(string)
Returns¶
The request parameters for the authorization endpoint encoded as an object with string values.
Example¶
function(config, request) {
"client_id": config.clientId,
"client_secret": config.clientSecret,
"grant_type": "refresh_code",
"refresh_token": request.refreshToken,
}
Deployment Notes¶
The auth middleware API relies on sharing cookies between the auth middleware and the Daml application.
One way to enable this is to expose the auth middleware and the Daml application under the same domain, e.g. through a reverse proxy.
Note that you will need to specify the external callback URI in that case using the --callback
command-line flag.
For example, assuming the following nginx configuration snippet:
http {
server {
server_name example.com
location /auth/ {
proxy_pass http://localhost:3000/;
}
}
}
You would invoke the OAuth 2.0 auth middleware with the following flags:
oauth2-middleware \
--callback https://example.com/auth/cb \
--address localhost
--http-port 3000
Some browsers reject Secure
cookies on unencrypted connections even on localhost.
You can pass the command-line flag --cookie-secure no
for testing and development on localhost to avoid this.