Use IdP Standard Claims

What happened?

In our existing application, we forward the access token to upstream app and get standard claims data from it. We want to avoid passing the IdP access token to upstream application and use JWT assertion token instead, but we need to pass some standard claim. For now we just know we can pass custom claim using jwt claim headers

Access Token

  "custom_user_id": "xxxx-xxxx-xxxx-xxxx",
  "ext_role": "",
  "iss": "",
  "sub": "auth0|xxxx123",
  "aud": [
  "iat": 1695266371,
  "exp": 1695352771,
  "azp": "SOME_CLIENT_ID",
  "scope": "openid profile email offline_access",
  "permissions": [ 

On the above example I can pass custom_user_id but cannot pass permissions as it is a “standard claim”.

What did you expect to happen?

I can pass the permissions as header, instead of the whole access token. Or, the permission is reflected in JWT Assertion Token

More Context

We use auth0 as the IdP. We do this because the existing app use permissions to do application-level authorization , but we do not want to pass the access token for security reason but we want to do minimal changes in the upstream apps.
Or are we approaching this problem the wrong way? Any suggestion?

The jwt_claims_headers option should support standard claims like permissions. The only unsupported claims are the ones we always define: (in other words they are supported, but don’t come directly from the IdP claims in the same way)

  • iss
  • aud
  • jti
  • exp
  • iat
  • sub
  • user
  • email
  • groups
  • sid
  • name

There may be a bug here or something else going on. I will investigate.

permissions doesn’t appear to be a claim added by Auth0. It is a custom claim which requires a post-login script in Auth0. We have documentation for adding groups claims: Auth0 | Pomerium. I attempted to write a script in Auth0 to add the permissions as a claim in a similar manner, but I wasn’t able to figure it out.

They have a post about it here: How to add Roles and Permissions to the ID Token using Actions? - Auth0 Community but it doesn’t include a concrete example of how to use the management API to query the permissions and add them as a claim.

Yes, we are trying to pass the permissions to the claim header / jwt access token at the moment, but have not found the way to do it. We are not really sure whether the permissions are custom or standard claims if it is added by the Management API.

Can we pass the value of the ‘unsupported’ claims that come directly from IdP claims in different way that you mentioned? This use case also talks about forwarding any value that exists in id / access token but not in jwt assertion header

Also , i tried a workaround, which is not really preferred, if the above issue can actually be addressed, by making a script in auth0 actions to make http call to the management API and get the user permissions. Then I set these permissions as custom claim in access token and pass them as req headers in pomerium.

api.accessToken.setCustomClaim("abc", ["hehe","haha"]);

But it turns out the pomerium can’t pass it if it is only set in access token so i need to add

api.idToken.setCustomClaim("abc", ["hehe","haha"]);

Why is that so?


   X-Custom-ABC: abc

Access Token

  "abc": [
  "permissions": [

Req Header

  "X-Custom-Abc": "hehe,haha", 

Hi Dennis,

That’s surprising that it would only work for the id token. I believe it should work for both. I’ll file an issue and investigate.

Hi Dennis,

Looking into this further, I’m not sure using access token claims will work. I believe Auth0 issues “opaque” access tokens by default. These are in a format that can only be used with the user info endpoint. To get JWT access tokens additional audiences need to be passed to the Auth0 API.

Since using the id token does seem to work, is it ok to just use that instead?

Hi Caleb,

I don’t think it is not a good solution in our use case. We find that management API in auth0 also has a relatively ‘low’ rate limit , I don’t think it is supposed to be for high-intensity flow such as login.

Also,CMIIW, but I don’t think we use opaque access token since we can decrypt the token directly