Adding custom claim to access token when using client credentials

In short I’m wondering how I can insert a custom claim into an access token when using the client credentials grant.

I have a SPA application that uses the implicit grant flow to get a token for the user. I have a rule in Auth0 to insert the username of the user as a custom claim in the token.

Code is below, and it works awesome.

function (user, context, callback) {
  var namespace = 'https://example.com/';
  context.accessToken[namespace + 'username'] = user.name;
  callback(null, user, context);
}

The application passes this token to an API endpoint where the API endpoint extracts out the username. This also works well.

The problems start to happen when I want to do an integration test against the API endpoint. This integration test needs to simply get a token with the custom claim username and try to call the API and make sure it’s working okay. I decided to use the client credentials grant as that way I can directly call the endpoint and get a token without having a front end website. The problem with this approach is that when the access token is returned, it does not have the same custom claim with the username.

Can you please let me know how it’s possible to use the client credentials grant flow and have the username as a custom claim?

Bonus point: Can you please explain why the system operates so differently? As in if i’m getting a token why is the rule not run in both circumstances? It appears the system behaves differently where in effect it’s doing the same operation, just through a different endpoint.

The explanation for the different behavior is not so much related to the different endpoints, but more due to the different OAuth2 grants being used. The SPA application is using the implicit grant which implies the notion of an end-user, more specifically, the application want to obtain an access token that allows it to call a resource server on-behalf of the user itselt.

In the second situation you’re using a client credentials grant that is meant for situation where a client application wants to access a resource on behalf of the client application itself; in this grant there is not an end-user involved.

The rules run as part of end-user associated grants and provide you with a user object associated with the user currently doing the login; for client credentials rules don’t run and the method available to customize the returned access token (client credentials hook) will also not have any user object available as the grant has no notion of user by default.

You have a couple of alternatives in order to have your integration test using a flow that does not require user interaction:

  • use the resource owner password credentials grant in association with a test user; this grant is just an HTTP request to the /oauth/token endpoint, but allows you to pass a username/password which means the access tokens is issued for that user in particular and as such rules will run.
  • if your API expects tokens signed with HS256 then you can issue tokens for the API yourself using the associated secret.
1 Like

Thanks so much @jmangelo! Very informative and spot on the money

Thanks so much @jmangelo! Very informative and spot on the money