Enriching Token Claims Using Cloudentity Extensions
Learn how to enrich claims for security tokens before the token is minted by the Cloudentity platform.
About Enriching Token Claims
With Extensions, Cloudentity enables developers to enrich claims for ID and access tokens issued by the platform. Developers can prepare JavaScript Extensions to modify the token claims before it is minted. Token claims can be enriched, for example, to:
Include data (such as user permissions) from an external system
Overwrite static attributes
Populate the token with risk information from external services
Populate token with fine-grained permissions for the user that resides in an external service
Populate token with business-related information about the user from external services.
Note
You can learn more about Cloudentity Extensions and enriching token claims by reading the Extending Cloudentity Capabilities.
Available Inputs
When creating Extension scripts that enrich claims for security tokens minted by the Cloudentity platform, developers have access to the following input objects within the script execution context:
client
- to have access to client application dataClient schema:
{ "application_type": "web", "application_types": [ "single_page", "server_web", "mobile_desktop", "service", "legacy", "dcr" ], "audience": [ "client_id" ], "authorization_server_id": "default", "backchannel_authentication_request_signing_alg": "string", "backchannel_client_notification_endpoint": "string", "backchannel_token_delivery_mode": "string", "backchannel_user_code_parameter": true, "client_id": "string", "client_id_issued_at": 0, "client_name": "My app", "client_secret": "stringstringstringstringstringst", "client_secret_expires_at": 0, "client_uri": "string", "description": "string", "developer_id": "string", "developer_metadata": { "property1": {}, "property2": {} }, "dynamically_registered": true, "grant_types": [ "password", "refresh_token", "client_credentials", "implicit", "authorization_code" ], "hashed_rotated_secrets": [ "string" ], "hashed_secret": "string", "id_token_encrypted_response_alg": "RSA-OAEP", "id_token_encrypted_response_enc": "A256GCM", "id_token_signed_response_alg": "ES256", "jwks": { "keys": [] }, "jwks_uri": "string", "logo_uri": "string", "metadata": { "property1": {}, "property2": {} }, "organisation_id": "5647fe90-f6bc-11eb-9a03-0242ac130003", "policy_uri": "string", "privacy": { "scopes": { "property1": { "pii_categories": [ { "name": "HIPAA" } ], "purpose": "string" }, "property2": { "pii_categories": [ { "name": "HIPAA" } ], "purpose": "string" } } }, "redirect_uris": [ "https://example.com/callback" ], "request_object_signing_alg": "none", "request_uris": [ "string" ], "require_pushed_authorization_requests": true, "response_types": [ "token", "id_token", "code" ], "rotated_secrets": [ "string" ], "scope": "email offline_access openid", "scopes": [ "email", "offline_access", "openid" ], "sector_identifier_uri": "https://api.jsonbin.io/b/5db6ef08688fed59d2841f1e", "software_id": "string", "software_statement": "string", "software_version": "string", "subject_type": "public", "system": true, "tenant_id": "string", "tls_client_auth_san_dns": "string", "tls_client_auth_san_email": "string", "tls_client_auth_san_ip": "string", "tls_client_auth_san_uri": "string", "tls_client_auth_subject_dn": "string", "tls_client_certificate_bound_access_tokens": true, "token_endpoint_auth_method": "client_secret_basic", "token_endpoint_auth_signing_alg": "none", "tos_uri": "string", "trusted": true, "userinfo_signed_response_alg": "none" }
grant_type
- to get the information about the authorization grant type that was requested by the client applicationExample values:
client_credentials
,token-exchange
,urn:openid:params:grant-type:ciba
For more information on available grant types, see Cloudentity Grant Types articles.
granted_scopes
- to have data about the scopes that are already granted to the client applicationSample input:
{ "granted_scopes": ["email", "openid"] }
authorize_request
- to have session data about the authorization request that concluded the call to the token endpoint. The developers have access to the original URL of the call to the authorize endpoint, and to the query parameters of this call.Sample input:
{ "authorize_request": { "url": "https://{tid}.eu.authz.cloudentity.io/{tid}/{aid}/oauth2/authorize", "query_params": { "prompt": ["login"] } } }
authn_ctx
- to have information about the authentication contextSample input:
{ "access_token": { "acr": "1", "aid": "default", "amr": [ "pwd" ], "aud": [ "default-demo", "spiffe://default.acp.local/default-profile", "spiffe://default.acp.local/default-oauth2", "spiffe://default.acp.local/default-user-privacy-consent" ], "exp": 1651057535, "iat": 1651053934, "idp": "default", "iss": "https://default.acp.local:8443", "jti": "6e3b9808-f0f5-4d2c-80c9-1f54cf7cbf6f", "nbf": 1651053934, "scp": [ "email", "introspect_tokens", "list_clients_with_access", "manage_consents", "offline_access", "openid", "profile", "revoke_client_access", "revoke_tokens", "view_consents" ], "st": "public", "sub": "9a663bf966861677ca77004a6b4c1fc87d11d78afeb245fb3549ab32783af3ab", "tid": "default" } }
You can also find an example usage of the
access_token
input object in the Sample Script section.id_token
- to be able to enrich claims within the minted identity tokenSample input:
{ "id_token": { "acr": "1", "amr": [ "pwd" ], "aud": "default-demo", "auth_time": 1651053934, "email": "jdoe@example.com", "email_verified": true, "exp": 1651057534, "family_name": "Doe", "given_name": "John", "iat": 1651053934, "idp": "default", "idpm": "static", "iss": "https://default.acp.local:8443", "jti": "dbb369b4-cc83-4302-81fb-122e05c92334", "name": "John Doe", "nonce": "c9khaqmk66ml1d1ibki0", "rat": 1651053934, "refresh_token_expires_at": 1653645935, "sub": "9a663bf966861677ca77004a6b4c1fc87d11d78afeb245fb3549ab32783af3ab" } }
You can also find an example usage of the
access_token
input object in the Sample Script section.
Tip
You can see the available inputs examples in the Extensions editor:
Available Output
Extensions modifying claims within different security tokens can produce the following output:
access_token
- to show the result of enriching claims within an access tokenid_token
- to show the result of enriching claims within an ID token
Example output:
{ "id_token": { "role": "manager" } } { "access_token": { "permissions": [ "delete_user", "block_user", "accept_payrise_request" ] } }
Tip
Extensions scripts do not override the entire content of an access token/ID token. The scripts update only those parts of a token that are explicitly defined in the Extension.
With Extensions that enrich token claims, you do not need to add any new attributes to your authentication context as the Extension is able to inject them dynamically.
Enrich Token Claims
When creating the Extension, use available inputs, outputs, and dependencies.
Tip
For instructions on how to create Cloudentity Extensions, test using test mode, and to learn what are recommended best practices when working with Extensions, see the Creating and Testing Extensions How-to article.
To check how Extensions modifying the login flow for end users work and look, see the Sample Script section.
Assign the Extension:
At the authorization server level in OAuth > Tokens & Claims > Claims > Claims list > Pre-token minting extension.
When the extension is attached at the authorization server level all client applications registered within the workspace are affected -- the token claims are enriched for all of them using the assigned extension.
At the client application level in Applications > Clients > OAuth > Custom claims and token enrichment > Pre-token minting extension.
Extensions attached at the client level affect only the client they are assigned to and are executed after Extensions at the server level (if there are any).
Verify enriched claims using Sandbox IDP and Demo Application/API
Sample Script
module.exports = async function(context) { const request = require('request-promise-native'); try { const response = await request({ method: 'GET', json: true, uri: 'https://raw.githubusercontent.com/LearnWebCode/json-example/master/pet-of-the-day.json' }); const pet_name = response.name; const pet_species = response.species; return { id_token: { pet: { name: pet_name, species: pet_species } } }; }catch(e) { console.error(e); return { pet: null }; } }
In the Extension above, a request is made to fetch the pet of the day and enrich an ID token with the pet
claim. If you wish, you can replace the id_token
input parameter to access_token
to enrich an access token. You can also enrich both tokens at the same time as shown below:
return { id_token: { pet: { name: pet_name, species: pet_species } } access_token: { pet: { name: pet_name, species: pet_species } } };
Verify Enriched Claims Using Sandbox IDP and Demo Application/API
If you wish to confirm enriched claims for your security tokens, you can use Cloudentity Sandbox IDP and Demo Application if it is enabled for the workspace you are working on. If it is not, you can use Cloudentity APIs and a token decoder like jwt.io.
Set up Sandbox IDP if is not available within the workspace you are working within.
If the workspace has the Demo Application available, authenticate as the user you have set up within the Sandbox IDP.
Tip
You can access the Demo Application in three ways:
In the WORKSPACE MANAGER by clicking the dropdown for the workspace and selecting Demo application.
Within the workspace overview (Dashboards > Overview) Connected portals right-hand panel.
By visiting the
https://{tid}.authz.cloudentity.io/{tid}/{wid}/demo
URL with your tenant identifier set for the{tid}
variable and the workspace identifier set for the{wid}
variable.
Depending on whether you enriched claims for an access token or id token (or both), investigate the claims for the token.
Your enriched claims should be visible as the part of the Claims tab as shown below:
If your workspace does not have a Demo Application available, you can get your token using any other client application and calling the Cloudentity OAuth 2.0 Token endpoint . Once you have the token, decode it using the jwt.io service to view the claims.
Tip
Remember that if you wish to get a particular token (for example, only an ID token), you need to configure the Response Types setting in your client application OAuth configuration (Applications > Clients > OAuth).