On this page

Customize tokens returned from Okta with a dynamic allow list

Note: Okta's Developer Edition makes most key developer features available by default for testing purposes. Okta's API Access Management product — a requirement to use Custom Authorization Servers — is an optional add-on in production environments.

This guide explains how to define custom Group claims for tokens that are returned from Okta, by using a dynamic allowlist to define user limits with a default or custom authorization server.


Learning outcomes

  • Customize Okta tokens with a dynamic allowlist.
  • Use a dynamic allowlist with an authorization server.

What you need


About the dynamic allow list

You can create a dynamic or static allowlist when you need to set Group allowlists on a per-app basis using both the org authorization server and a custom authorization server. If you have a large number of Groups but only 20 Groups apply to your app, you don't want to run through all of your Groups every time a Groups claim is created. This process optionally uses Okta's flexible app profile, which accepts any JSON-compliant content, to create an allowlist of Groups that can then easily be referenced.

Additionally, you can add a Groups claim to ID tokens for any combination of App Groups and User Groups to perform single sign-on (SSO) using the org authorization server. You can also add a Groups claim to ID tokens and access tokens to perform authentication and authorization using a custom authorization server.

See Customize tokens returned from Okta when you want to define your own custom claims. For example, you might want to add a user's email address to an access token and use that to uniquely identify the user, or you may want to add information stored in a user profile to an ID token.

Request a token that contains the custom claim

There are sections in this guide that include information on building a URL to request a token that contains a custom claim. These sections refer you to this page for the specific steps to build the URL to request a claim and decode the JWT to verify that the claim was included in the token. Specific request and payload examples remain in the appropriate sections. Move on to the next section if you don't currently need these steps.

To test the full authentication flow that returns an ID token or an access token, build your request URL:

  1. Obtain the following values from your OpenID Connect application, both of which can be found on the application's General tab:

    • Client ID
    • Redirect URI
  2. Use the authorization server's authorization endpoint:

    Note: See Authorization servers for more information on the types of authorization servers available to you and what you can use them for.

    • An org authorization server authorization endpoint looks like this:

      https://${yourOktaDomain}/oauth2/v1/authorize

    • A custom authorization server authorization endpoint looks like this:

      https://${yourOktaDomain}/oauth2/${authorizationServerId}/v1/authorize

    Note: If you add the claim to the default custom authorization server, the ${authorizationServerId} is default.

    You can retrieve a custom authorization server's authorization endpoint using the server's metadata URI:

    ID token https://${yourOktaDomain}/oauth2/${authorizationServerId}/.well-known/openid-configuration

    Access token https://${yourOktaDomain}/oauth2/${authorizationServerId}/.well-known/oauth-authorization-server

  3. Add the following query parameters to the URL:

    • Your OpenID Connect application's client_id
    • The response type, which for an ID token is id_token and an access token is token

    Note: The examples in this guide use the Implicit flow. For the Authorization Code flow, the response type is code. You can exchange an authorization code for an ID token and/or an access token using the /token endpoint.

    • A scope, which for the purposes of the examples is openid. When you are adding a Groups claims, both the openid and the groups scopes are included.
    • Your OpenID Connect application's redirect_uri
    • Values for state and nonce, which can be anything

    Note: All of the values are fully documented on the Obtain an Authorization Grant from a user page.

    The resulting URL looks something like this:

    curl -X GET
    "https://${yourOktaDomain}/oauth2/${authorizationServerId}/v1/authorize?client_id=examplefa39J4jXdcCwWA
    &response_type=id_token
    &scope=openid
    &redirect_uri=https%3A%2F%2FyourRedirectUriHere.com
    &state=myState
    &nonce=myNonceValue"
    

    Note: The response_type for an access token looks like this: &response_type=token

  4. After you paste the request into your browser, the browser is redirected to the sign-in page for your Okta org. Enter the credentials for a User who is mapped to your OpenID Connect application, and then the browser is directed to the redirect_uri that you specified in the URL and in the OpenID Connect app. The response contains an ID token or an access token, as well as any state that you defined.

    ID token

    https://yourRedirectUriHere.com#id_token=eyJraWQiOiIxLVN5[...]C18aAqT0ixLKnJUR6EfJI-IAjtJDYpsHqML7mppBNhG1W55Qo3IRPAg&state=myState
    

    Access token

    https://yourRedirectUriHere.com#access_token=eyJraWQiOiIxLVN5M2w2dFl2VTR4MXBSLXR5cVZQWERX[...]YNXrsr1gTzD6C60h0UfLiLUhA&token_type=Bearer&expires_in=3600&scope=openid&state=myState
    
  5. To check the returned ID token or access token payload, you can copy the value and paste it into any JWT decoder (for example: https://token.dev (opens new window)). Using a JWT decoder, confirm that the token contains all of the claims that you are expecting, including the custom one. If you specified a nonce, that is also included.

Add a Groups claim with a dynamic allow list

You can use Okta Expression Language (EL) Group Functions with dynamic allowlists. Three Group functions help you use dynamic group allowlists: contains, startsWith, and endsWith. These functions return all of the Groups that match the specified criteria without needing to have Groups specified in the app.

You can use this function anywhere to get a list of Groups of which the current user is a member, including both User Groups and App Groups that originate from sources outside of Okta, such as from Active Directory and Workday. Additionally, you can use this combined, custom-formatted list for customizable claims into access and ID tokens that drive authorization flows. All three functions have the same parameters:

Parameter Description Nullable Example Values
app Application type or App ID FALSE "OKTA","0oa13c5hnZFqZsoS00g4", "active_directory"
pattern Search term FALSE "Eastern-Region", "Eastern", "-Region"
limit Maximum number of Groups returned. Must be a valid EL expression and evaluate to a value between 1 to 100. Note: When you use the Authorization Code and Authorization Code with PKCE flows, you can specify any number of maximum groups returned. FALSE 1, 50, 100

Important: When you use Groups.startWith, Groups.endsWith, or Groups.contains, the pattern argument is matched and populated on the name attribute rather than the group's email (for example, when using G Suite). If you are targeting groups that may have duplicate group names (such as Google Groups), use the getFilteredGroups Group function instead.

Example: getFilteredGroups({"00gml2xHE3RYRx7cM0g3"}, "group.name", 40) )

See the Parameter Examples section of Use group functions for static group allowlists for more information on the parameters used in this Group function.

You can use a dynamic group allowlist with both the org authorization server and a custom authorization server:

Use a dynamic group allow list with the org authorization server

To use the Group Functions to create a token using a dynamic group allowlist, create a Groups claim on an app. For an org authorization server, you can only create an ID token with a Groups claim.

Note: In this example, the user signing in to your app is assigned to a group called "IT".

  1. In the Admin Console, go to Applications > Applications.
  2. Select the client application that you want to configure.
  3. Go to the Sign On tab and click Edit in the OpenID Connect ID Token section.
  4. In the Groups claim type section, select Expression.
  5. In the Groups claims filter section, leave the default name groups (or add it if the box is empty) and add one of the three functions with the criteria for your dynamic group allowlist. For this example, use Groups.startsWith("OKTA", "IT", 10).
  6. Click Save.

Request an ID token that contains the Groups claim

To test the full authentication flow that returns an ID token, build your request URL. The scopes that you need to include as query parameters are openid and groups. For the specific steps on building the request URL, receiving the response, and decoding the JWT, see Request a token that contains the custom claim.

The resulting URL looks something like this:

curl -X GET
"https://${yourOktaDomain}/oauth2/v1/authorize?client_id=examplefa39J4jXdcCwWA
&response_type=id_token
&scope=openid%20groups
&redirect_uri=https%3A%2F%2FyourRedirectUriHere.com
&state=myState
&nonce=myNonceValue"

The decoded JWT looks something like this:

{
  "sub": "00uixa271s6x7qt8I0h7",
  "ver": 1,
  "iss": "https://{yourOktaDomain}",
  "aud": "0oaoiuhhch8VRtBnC0h7",
  "iat": 1574207471,
  "exp": 1574211071,
  "jti": "ID.3xqAvJ3YTofkkrF0FpapgxFEExGWOEoyhWspO6SFQtA",
  "amr": [
    "pwd",
    "mfa",
    "kba"
  ],
  "idp": "00oixa26ycdNcX0VT0h7",
  "nonce": "UBGW",
  "auth_time": 1574207041,
  "groups": [
    "IT"
  ]
}

Use a dynamic group allow list with a custom authorization server

To use the Group Functions to create an ID token or an access token using a dynamic group allowlist, create a Groups claim and a Groups scope in the custom authorization server. For this example, we are adding a claim for use with an access token.

Note: In this example, the user signing in to your app is assigned to a group called "IT".

  1. In the Admin Console, from the Security menu, select API, and then select the custom authorization server that you want to configure.

  2. Go to the Claims tab and click Add Claim.

  3. Enter a name for the claim. For this example, name it dynamic_group.

  4. In the Include in token type section, leave Access Token selected.

  5. Leave Expression as the Value type.

  6. Enter the following expression as the Value: Groups.startsWith("OKTA", "IT", 10)

    Important: When you use Groups.startWith, Groups.endsWith, or Groups.contains, the pattern argument is matched and populated on the name attribute rather than the group's email (for example, when using G Suite). If you are targeting groups that may have duplicate group names (such as Google Groups), use the getFilteredGroups Group function instead.

    Example: getFilteredGroups({"00gml2xHE3RYRx7cM0g3"}, "group.name", 40) )

    See the Parameter Examples section of Use group functions for static group allowlists for more information on the parameters used in this Group function.

  7. Click Create.

  8. Select the Scopes tab and click Add Scope.

  9. Add groups as the scope Name and DisplayName, and then select the Metadata check box.

  10. Click Create.

Request an access token that contains the Groups claim

To test the full authentication flow that returns an access token, build your request URL. The scopes that you need to include as query parameters are openid and groups. For the specific steps on building the request URL, receiving the response, and decoding the JWT, see Request a token that contains the custom claim.

The resulting URL looks something like this:

curl -X GET
"https://${yourOktaDomain}/oauth2/${authorizationServerId}/v1/authorize?client_id=examplefa39J4jXdcCwWA
&response_type=token
&scope=openid%20groups
&redirect_uri=https%3A%2F%2FyourRedirectUriHere.com
&state=myState
&nonce=myNonceValue"

The decoded JWT looks something like this:

{
  "ver": 1,
  "jti": "AT.lsZ5XmKiK4KxpKs2IDUBKMRgfMhiB2i2hTBZEM7epAk",
  "iss": "https://{yourOktaDomain}/oauth2/ausocqn9bk00KaKbZ0h7",
  "aud": "https://{yourOktaDomain}",
  "iat": 1574270245,
  "exp": 1574273845,
  "cid": "0oaoiuhhch8VRtBnC0h7",
  "uid": "00uixa271s6x7qt8I0h7",
  "scp": [
    "groups",
    "openid"
  ],
  "sub": "joe.user@okta.com",
  "dynamic_group": [
    "IT"
  ]
}

See also

Other ways that you can customize claims and tokens: