Add Roles/Claims to the access token via Login Flow

I want to use roles on auth0.
But the roles are not automatically in the token.

I tried:

exports.onExecutePostLogin = async (event, api) => {
exports.onExecutePostLogin = async (event, api) => {
if ( &&“”) && === “My SPA”) {
api.access.deny(Access to ${} is not allowed.);
// Define a namespace (URL you control) to avoid conflicts with standard OIDC claims
const namespace = ‘’;

// Log the incoming user metadata and app_metadata
console.log(‘User metadata:’, event.user.user_metadata);
console.log(‘App metadata:’, event.user.app_metadata);

// Retrieve roles from user’s app_metadata, or assign a default role if none exist
const roles = (event.user.app_metadata && event.user.app_metadata.roles)
? event.user.app_metadata.roles
: [‘default_role’];

// Log the roles being set to the token
console.log(‘Roles being set to the token:’, roles);

// Set custom claims in both the ID and access tokens
api.idToken.setCustomClaim(${namespace}roles, roles);
api.accessToken.setCustomClaim(${namespace}roles, roles);

// Confirm the claims have been set in the logs
console.log(‘Custom claims set in ID Token:’, ${namespace}roles, roles);
console.log(‘Custom claims set in Access Token:’, ${namespace}roles, roles);
api.user.setUserMetadata(“favorite_color”, “blue”);
if (event.authorization) {
api.idToken.setCustomClaim(${namespace}/roles, event.authorization.roles);
api.accessToken.setCustomClaim(${namespace}/roles, event.authorization.roles);

const namespace2 = ‘’;

const roles2 = event.user.app_metadata && event.user.app_metadata.roles ?
event.user.app_metadata.roles : [‘default_role’];

api.idToken.setCustomClaim(${namespace}/roles, roles2);
api.accessToken.setCustomClaim(${namespace}/roles, roles);

But it does not add it to the token too.
Here are my Action Details =>

“action_name”: “Add Roles”,
“response”: {
“logs”: “User metadata: { favorite_color: ‘blue’, test: ‘test’ }\nApp metadata: {}\nRoles being set to the token: [ ‘default_role’ ]\nCustom claims set in ID Token: / [ ‘default_role’ ]\nCustom claims set in Access Token: https:/”,
“stats”: {
“total_request_duration_ms”: 375,
“total_runtime_execution_duration_ms”: 372,
“runtime_processing_duration_ms”: 4,
“action_duration_ms”: 312,
“runtime_external_call_duration_ms”: 56,
“boot_duration_ms”: 60,
“network_duration_ms”: 3
“started_at”: “2024-04-13T12:49:45.453485604Z”,
“ended_at”: “2024-04-13T12:49:45.829570334Z”

So it clearly logs. I also banned my user from login => it was not anymore possible to login

What do I wrong?

On angular side I use:

domain: ‘’,
clientId: ‘333’,
authorizationParams: {
redirect_uri: window.location.origin,
audience: “api”,
scope: ‘openid profile email’,

I use => this.auth.getAccessTokenSilently(). and => this.auth.user$


  • How can I fix it?
  • Is it a good idea to add roles to the token (Keycloak used it => wich we used before)
  • Is my scope correct?
  • Do I need for my spring boot application the same “Auth0 Application” as for my Angular app ? ( I use at the moment 2 apps: “Single Page Application” and “Regular Web Application”)

Hey there @max12234 !

Thanks for the context and your script content!
I believe, in your Action script, you are missing apostrophes for the setCustomClaim arguments:

api.idToken.setCustomClaim(${namespace}/roles, roles2);
api.accessToken.setCustomClaim(${namespace}/roles, roles);

Can you please try this way (in every relevant place)? :slight_smile:

api.idToken.setCustomClaim('${namespace}/roles', roles2);
api.accessToken.setCustomClaim('${namespace}/roles', roles);

It works for me this way, so please let us know if that fixes your issue!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.