Post Login Action not Placing Role in Token

I am attempting to add roles to the access token with the example code:

exports.onExecutePostLogin = async (event, api) => {
const namespace = ‘https://artapi.com’;
if (event.authorization) {
api.idToken.setCustomClaim(${namespace}/roles, event.authorization.roles);
api.accessToken.setCustomClaim(${namespace}/roles, event.authorization.roles);
}
}

When I login I see no difference in the token. I logging in for a react app using the @auth0/auth0-react library.

I am new to Actions. Where am I going wrong?

1 Like

I am facing the same issue, we want to get the token updated with user GitHub-teams, our rule works fine, converting that to action is not working, can some on help to get the token updated with git hub teams.

Hey there @kcwardwell :slight_smile:

Is this your action code verbatim? I did notice that your claims are missing quotes which I believe will cause issues. It should be:

exports.onExecutePostLogin = async (event, api) => {
  const namespace = 'https://my-app.example.com';
  if (event.authorization) {
    api.idToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
    api.accessToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
  }
}

Aside from this, can you confirm that you have attached the action to the Post Login Flow? I was just able to test this on my end and everything seems to be functioning as expected.

1 Like

Hey there @vijay-veeranki welcome to the community! :cowboy_hat_face:

Are you using the same action? Do you mind sharing it here?

1 Like

Hi,

Thanks for your reply, please find our action converted from a rule which is working fine.

Created this action and added it to the login flow.

Action:

exports.onExecutePostLogin  = async (event, api) =>  {
  const _ = require('lodash');
  var request = require('request');

  // Apply to 'github' connections only
  if(event.connection.strategy === 'github'){
    // Get user's Github profile and API access key
    var github_identity = _.find(event.user.identities, { connection: 'github' });

    // Get list of user's Github teams
    var teams_req = {
      url: 'https://api.github.com/user/teams',
      headers: {
        'Authorization': 'token ' + github_identity.access_token,
        'User-Agent': 'request'
      }
    };

    request(teams_req, function (err, resp, body) {
      if (resp.statusCode !== 200) {
        return api.access.deny('Error retrieving teams from github: ' + body || err);
      }

      // Construct list of user's Github teams
      // The team slug is used, to normalise whitespace, capitalisation etc.
      var git_teams = JSON.parse(body).map(function (team) {
        if (team.organization.login === "orgname") {
          return "github:" + team.slug;
        }
      });

      // Add team list to the user's JWT as a custom claim
      //
      // Custom OIDC claims should be prefixed with a unique value
      // to prevent clashes with claims from other sources.
      // Common practice is to use a URL
      api.idToken.setCustomClaim[event.secrets.K8S_OIDC_GROUP_CLAIM_DOMAIN] = git_teams;
      return;
    });
  } else {
    return;
  }
};

the rule which is working fine, which we are using for couple of years:

function (user, context, callback) {
  var request = require('request');

  // Apply to 'github' connections only
  if(context.connection === 'github'){
    // Get user's Github profile and API access key
    var github_identity = _.find(user.identities, { connection: 'github' });

    // Get list of user's Github teams
    var teams_req = {
      url: 'https://api.github.com/user/teams',
      headers: {
        'Authorization': 'token ' + github_identity.access_token,
        'User-Agent': 'request'
      }
    };

    request(teams_req, function (err, resp, body) {
      if (resp.statusCode !== 200) {
        return callback(new Error('Error retrieving teams from github: ' + body || err));
      }

      // Construct list of user's Github teams
      // The team slug is used, to normalise whitespace, capitalisation etc.
      var git_teams = JSON.parse(body).map(function (team) {
        if (team.organization.login === "orgname") {
          return "github:" + team.slug;
        }
      });

      // Add team list to the user's JWT as a custom claim
      //
      // Custom OIDC claims should be prefixed with a unique value
      // to prevent clashes with claims from other sources.
      // Common practice is to use a URL
      context.idToken[configuration.K8S_OIDC_GROUP_CLAIM_DOMAIN] = git_teams;

      return callback(null, user, context);
    });
  } else {
    return callback(null, user, context);
  }
}

@tyf after some debugging noticed below

event.user.identities used in action are not getting the same result as user.identities in rules.

rules are giving

    "headers": {
      "Authorization": "token gho_xxxxxxxxxxxxxx",
      "User-Agent": "request"
    }

Action is giving token as “undefined”

    "headers": {
      "Authorization": "token undefined",
      "User-Agent": "request"
    },

Thanks for following up with your findings, very helpful!

I was unaware of the difference here, but it looks like with actions you need to poll the Management API in order to extract the user’s IDP access token as opposed to being able to extract it directly from Identities like was possible in rules.

I set up a basic action wherein I authenticated a user at google, and attempted to extract the access token the same way you did and got undefined as well. However, getting the user via the Management API I can indeed see/extract the IDP access_token so I believe you need to add that step in your action. Please see:

Hope this helps!

1 Like