Token Exchange Populate Lambda
On this page
This feature requires an Enterprise plan.
1.70.0
A Token Exchange Populate lambda modifies the claims of an access token issued through token exchange. FusionAuth runs this lambda after the policy engine allows an exchange and before it signs the token. The lambda is optional.
Lambda Structure#
The lambda must contain a function named populate with the following signature:
function populate(jwt, exchange, context) {
// Lambda code goes here
}
The function accepts the following parameters:
jwt: the claims of the token FusionAuth is about to sign. This object is mutable.exchange: information about the exchange. This object is read-only.context: access to secrets. This object is read-only.
The jwt Object#
Before the lambda runs, the jwt object contains the claims FusionAuth built from the policy decision and the subject token, including sub, aud, scope, act, client_id, exp, and tid. The lambda can add claims, change claims, and remove claims by setting them to null, with the following restrictions.
FusionAuth discards any changes to the following reserved claims:
actamrapplicationIdauth_timeauthenticationTypeclient_idcnfgtyiatissjtimay_actsidsubtidtty
The lambda can only narrow the following claims:
aud: FusionAuth keeps only the values that the policy engine granted. If no granted values remain, or the lambda removes the claim, FusionAuth restores the granted audiences.scope: FusionAuth keeps only the scopes that the policy engine granted. If no granted scopes remain, or the lambda removes the claim, FusionAuth restores the granted scopes.exp: FusionAuth ignores a value later than the original expiration.
FusionAuth copies the amr, applicationId, auth_time, authenticationType, and sid claims from the subject token when they are present. FusionAuth doesn't copy any other claims from the subject token. To carry over another claim, copy it from exchange.subjectToken.
To avoid conflicts with registered claims and claims FusionAuth adds in the future, give custom claims a namespaced name, such as https://example.com/department.
The exchange Object#
subjectTokenThe claims of the validated subject token.
entityThe exchanger Entity, without its client secret. See the Entity API for the fields of this object.
audiencesThe audiences the policy engine granted.
scopesThe scopes the policy engine granted.
intentThe value of the intent request parameter. Undefined when the request doesn't include intent.
stateThe value of the state request parameter. Undefined when the request doesn't include state.
The context Object#
services.secrets Provides access to secrets through context.services.secrets.get('<secret-name>').
Errors#
If the lambda throws an exception, FusionAuth rejects the exchange with a 422 status code and a server_error error, and records the attempt in the audit log with the POPULATE_LAMBDA_ERROR outcome. To keep an exchange from failing because of an optional step, such as a call to an external service, catch exceptions in the lambda.
Assigning the Lambda#
To assign the lambda in the Admin UI:
- Navigate to Tenants and click on the Tenant.
- Select the OAuth tab.
- In the Token exchange settings section, select the lambda in Token exchange populate lambda.
- Click .
To assign the lambda with the Tenant API, set tenant.tokenExchangeConfiguration.populateLambdaId to the lambda's Id.
Examples#
Add Claims From the Exchanger Entity#
This lambda copies values from the exchanger Entity's data into the token:
function populate(jwt, exchange, context) {
const data = exchange.entity.data || {};
if (data.department) {
jwt['https://example.com/department'] = data.department;
}
if (exchange.intent) {
jwt['https://example.com/intent'] = exchange.intent;
}
}
Copy a Claim From the Subject Token#
This lambda carries a custom claim from the subject token into the issued token:
function populate(jwt, exchange, context) {
const orgId = exchange.subjectToken['https://example.com/org_id'];
if (orgId) {
jwt['https://example.com/org_id'] = orgId;
}
}
Narrow the Scope and Lifetime#
This lambda removes write access and shortens the lifetime of tokens exchanged for a reporting service:
function populate(jwt, exchange, context) {
if ((exchange.audiences || []).indexOf('reporting-service') === -1) {
return;
}
const readOnly = (exchange.scopes || []).filter(scope => scope.indexOf(':write') === -1);
if (readOnly.length > 0) {
jwt.scope = readOnly.join(' ');
}
var maxExp = jwt.iat + 300;
if (jwt.exp > maxExp) {
jwt.exp = maxExp;
}
}
Related
An overview of FusionAuth's lambdas, which are pluggable JavaScript code that run at various points in the user lifecycle.
An overview of the JWT populate lambda.
API documentation for the FusionAuth Vend a JWT API.
API documentation for the FusionAuth Retrieve a Token Exchange Chain API.