Simplified JWT access token creation in Auth0

Auth0 has recently introduced its new Actions platform as a successor of the Rules and Hooks platform:

I wanted to implement the most simple way of issuing access tokens for a Daml ledger, and found the following:

In Auth0, we can attach arbitrary data to a user profile, so I attached the whole set of custom claims a Daml ledger requires in an access token:

This can be set by an admin, who creates the user in Auth0, through the Auth0 management API, in parallel with allocating the ledger party for the user.

Based on this set of data, we can add the custom claims to the access token with a simple custom action in Auth0:

After creating the custom action, we can include the action into the login flow.

After this, if a Daml application redirects its user to the Auth0 authorize endpoint with this URL:

https://<your-auth0-tenant-domain>.com/authorize?response_type=token&audience=https%3A%2F%2Fdaml.com%2Fledger-api&client_id=<your-client-id>&redirect_uri=http://<your-daml-app-url>/auth/cb&state=12345 

and the user authenticates on the Auth0 Universal Login screen, the user gets redirected to the Daml application with the access token in the URL hash fragment:

http://<your-daml-app-url>/auth/cb#access_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5rVkNRVVpFUmpSRk1qY3hOa1U1UmpaQ1JVSXdNa001UVVRNU9USXdPRFZCTXpkRE0wUkNOdyJ9.eyJodHRwczovL2RhbWwuY29tL2xlZGdlci1hcGkiOnsiYWN0QXMiOlsiYWxpY2UiXSwiYWRtaW4iOmZhbHNlLCJhcHBsaWNhdGlvbklkIjpudWxsLCJsZWRnZXJJZCI6ImFhYWFhYWFhYS1iYmJiLWNjY2MtZGRkZC1lZWVlZWVlZWVlZWUiLCJwYXJ0aWNpcGFudElkIjpudWxsLCJyZWFkQXMiOlsiYm9iIl19LCJpc3MiOiJodHRwczovL2Rldi1ucW4wd2Vqay5ldS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NjA4ZmVmN2RiMTVjM2YwMDY5MGZmY2FjIiwiYXVkIjoiaHR0cHM6Ly9kYW1sLmNvbS9sZWRnZXItYXBpIiwiaWF0IjoxNjIxNDQ1MDI3LCJleHAiOjE2MjE0NTIyMjcsImF6cCI6IkJzcWp3c0pqdHd1UkZuR0EwcVJEWlRjbEVsR1Y3a1BLIiwic2NvcGUiOiIifQ.VzfgBgYGqhQsyNAxpv0UmNSTbSl5t7Lsw1ctHVInmZ4CfBJ15GVVfD97Ajx3snefllxaMYXBR8IfARcekaQVnlwvqkJESVh7Lw3wIWoIdDstrx9kass8s5wBp8Ge6BtEN44ozaizj5m8EQv_m_H7pqP1idM2zvitzQ6GvtYbaaX7NBwhw7cy0SdZeGZNdic-LoQNV3l8Aa_iH6rvipmc1bfBuJcpAnGjOw2ID8wP5jHIlFbUbUBOpWWR3EYF_lvj_tXa0yNxP2oJoTsY_W2pfT6HNf_qnuVC0uxWfM9GIyuCsqVAN4ZlRysIdfOVxbENlqSb5v3tk9D8dFwqL-xbkw&expires_in=7200&token_type=Bearer&state=12345

We can check that the access token indeed contains the custom claims we have set in the user profile:

Of course, putting the JWT token into the response URL is not the safest way of access token handling. You have safer options by choosing an alternative authorization flow.

See the details of the Implicit Grant flow which is used here: SPA + API: Solution Overview

4 Likes

This is exactly what I was going to look into next.

Thanks!

3 Likes

The next step is to implement this flow in the React UI, for which Auth0 provides this tutorial: Auth0 React SDK Quickstarts: Login

And of course we have excellent guides on the Daml blog which can be used mutatis mutandis (these guides were written before the new Auth0 Actions platform, using the legacy Rules and Hooks platform):

1 Like

JWT token as a URL parameter is a definite code smell and to be avoided. These are written to logs and are reusable

I haven’t looked at the new Actions capability but the blog post part 2 demonstrated both end user 3 phase oAuth logins and 2-phase service account logins to get valid tokens. I’ll check out Actions to see if we need to update the blog.

The blog repo also provides a very simplistic set of scripts and services for local JWT token generation for local non-Auth0 testing.

3 Likes

Thanks @nycnewman, I agree, this is just the first step. I want to proceed in an agile way, meaning in small steps which work, even if at the beginning in a suboptimal way.

What would be of great help to me is a version of the Daml UI template which uses a really robust way of Auth0 access token handling.

See also my question:

2 Likes

Looks like Robin responded to you on that.

Could you expand a bit on the issue here? As far as I’m aware the fragment is specifically not part of the search params and is not sent by browsers to the HTTP server. Which logs are you concerned about? I’d assume if an attacker has access to your local browsing history you’ve pretty much already lost.

1 Like

Thinking about this more, the main issue I can think of regarding the fragment is that it’s accessible to all JS on the page, not just the bits of JS you intend it for. This should not be an issue if everything else about the page is perfect, but any vector of js code injection (improperly sanitized user content, poisoned dependencies, etc.) would have access to this information. I can’t think of a way to avoid that, though, as long as authentication has to be done purely client-side.

Usually the right solution to this is to put credentials in an httpOnly cookie (on a server that refuses CORS), but that’s only an option if you can control the backend and have your authentication on the same domain as your app.

2 Likes

Thanks foe the information. I’ll be sure to keep an eye on this thread. Looking for the same information.

Official Site

Hi @Godfrey,

In the next Daml SDK version (1.17.0), the create-daml-app template will come out-of-the-box with Auth0 support, and we’ll be adding a documentation page for a fully authenticated Auth0 setup (i.e. the Auth-0 side of this equation). I believe 1.17.0 is currently schedule for some time within the next two weeks.

1 Like

Great news!