How to retrieve user_metadata in id_token or access_token

How to retrieve user_metadata in id_token or access_token?

I am able to retrieve the metadata calling /user-info using a rule:

function (user, context, callback) {
  var namespace = 'https://my-app.io/';   
  var organization = user.user_metadata.organization;
  context.idToken[namespace + 'organizationId'] = user.user_metadata.organization.id;
  callback(null, user, context);
}

Following this tutorial it states that:

Custom claims may still be added, but must conform to a namespaced format to avoid possible collisions with standard OIDC claims.

However, the returned id_token doesn’t contain organizationId.

Is it a bug?

How do i retrieve the access_token

I setup auth0.WebAuth in js in in the service AuthService:

class AuthService {

  constructor () {
    this.authenticated = this.isAuthenticated()
    this.authNotifier = new EventEmitter()
    this.login = this.login.bind(this)
    this.setSession = this.setSession.bind(this)
    this.logout = this.logout.bind(this)
    this.isAuthenticated = this.isAuthenticated.bind(this)
    this.auth0 = new auth0.WebAuth({
      domain: process.env.AUTH0_DOMAIN,
      clientID: process.env.AUTH0_CLIENT_ID,
      redirectUri: process.env.AUTH0_REDIRECT_URI,
      audience: 'https://api.my-app.io',
      responseType: 'token id_token',
      scope: 'user_metadata openid profile',
      leeway: 30
    })
  }

We use the hosted login page on https://amio.eu.auth0.com. After a successful login, a redirect brings us to our callback page where store access_token and other stuff to local storage:

setSession (authResult) {
    // Set the time that the access token will expire at
    let expiresAt = JSON.stringify(
      authResult.expiresIn * 1000 + new Date().getTime()
    )
    localStorage.setItem('access_token', authResult.accessToken)
    localStorage.setItem('id_token', authResult.idToken)
    localStorage.setItem('expires_at', expiresAt)
    this.authNotifier.emit('authChange', {authenticated: true})
  }

Did a quick test with a web application client and the rule you showed (with an hardcoded organization identifier instead of reading from metadata) and I was not able to reproduce the situation. The only time the claim was not included in the ID token was when I hardcoded undefined as the value, but that also meant that /userinfo did not return so given you can see it when calling the endpoint this might not explain the situation even if your user.user_metadata.organization.id was undefined.

I would suggest you to update the question with information about how you’re obtaining the ID token (which endpoint, method, options, etc) and also information about client settings like application type, if it’s has OIDC conformance enabled and any other non-sensitive setting that you may feel relevant to disclose.

Thx for responding me jmangelo. I have updated my question with some of the info you asked me for. Do you need something else?

All of a sudden, the code started to work. For others that struggle with feature too, I’m adding a code snippet of our rule:

function (user, context, callback) {
  console.log('add-user_metadata-to-token_id - start');
  console.log('add-user_metadata-to-token_id - user ', user);
  console.log('add-user_metadata-to-token_id - context: ', context);
  var namespace = 'https://my-app.io/';
      
  var organization = user.user_metadata.organization;
    context.idToken[namespace + 'organizationId'] = user.user_metadata.organization.id;
  context.accessToken[namespace + 'organizationId'] = user.user_metadata.organization.id;
  
  console.log('add-user_metadata-to-token_id - idToken', context.idToken);
  console.log('add-user_metadata-to-token_id - accessToken', context.accessToken);
  
  callback(null, user, context);
}function (user, context, callback) {
  console.log('add-user_metadata-to-token_id - start');
  console.log('add-user_metadata-to-token_id - user ', user);
  console.log('add-user_metadata-to-token_id - context: ', context);
  
  var namespace = 'https://amio.io/';
  
  
  var organization = user.user_metadata.organization;
    context.idToken[namespace + 'organizationId'] = user.user_metadata.organization.id;
  context.accessToken[namespace + 'organizationId'] = user.user_metadata.organization.id;
  
  console.log('add-user_metadata-to-token_id - idToken', context.idToken);
  console.log('add-user_metadata-to-token_id - accessToken', context.accessToken);
  
  callback(null, user, context);
}