Dynamic Claims
Dynamic claims in the OIDC ID Token Credential Provider, JWT-SVID Token Credential Provider, and X.509-SVID Credential Provider place values from the requesting identity in the credential data. These values produce personalized, context-aware credentials that reflect the workload or user behind the request.
Dynamic claims draw from the identity evidence a Trust Provider validated and from the process environment of Agent Proxy or Aembit CLI. See Supported claim sources.
For the OIDC ID Token and JWT-SVID Token Credential Providers, dynamic expressions resolve in custom claims and the subject field. For the X.509-SVID Credential Provider, X.509 certificates do not carry arbitrary custom claims, so dynamic expressions resolve in the certificate’s Subject and Spiffe ID identity fields instead.
This functionality proves particularly useful wherever a credential must carry the requesting workload’s or user’s own attributes, such as in cloud-native applications, CI/CD pipelines, or microservices architectures.
How dynamic claims work
Section titled “How dynamic claims work”Dynamic claims operate with two main components:
- Template Definition - Define dynamic values in Credential Provider configuration using expressions instead of static values
- Runtime Resolution - Aembit collects the referenced information and replaces template variables with actual values
The process follows these steps:
- You configure template expressions in any Credential Provider field that accepts dynamic expressions
- When a workload requests a credential, the Trust Provider validates the incoming identity evidence, such as an OIDC token or a SAML 2.0 response
- Aembit extracts the referenced values from that evidence, or from the process environment, using your template expressions
- Aembit inserts the extracted values into the generated credential
Dynamic claims syntax
Section titled “Dynamic claims syntax”Dynamic claims use this syntax: ${expression}
Basic syntax patterns
Section titled “Basic syntax patterns”- OIDC Token Claims:
${oidc.identityToken.decode.payload.claim_name} - GitLab Token Claims:
${gitlab.identityToken.decode.payload.claim_name} - GitHub Token Claims:
${github.identityToken.decode.payload.claim_name} - SAML Assertion Claims:
${saml.response.subject.nameId} - Environment Variables:
${os.environment.VARIABLE_NAME} - Combined Values:
${oidc.identityToken.decode.payload.user_login}_suffix
Common expression examples
Section titled “Common expression examples”| Expression | Description | Example Result |
|---|---|---|
${oidc.identityToken.decode.payload.user_email} | Extract workload email from OIDC token | workload@company.com |
${oidc.identityToken.decode.payload.user_login} | Extract workload login/username | ci-workload |
${oidc.identityToken.decode.payload.groups} | Extract workload groups | ["developers", "admins"] |
${gitlab.identityToken.decode.payload.project_path} | Extract GitLab project path | group/project |
${gitlab.identityToken.decode.payload.ref} | Extract GitLab branch/tag reference | main |
${gitlab.identityToken.decode.payload.job_id} | Extract GitLab CI job ID | 123456789 |
${github.identityToken.decode.payload.actor} | Extract GitHub workflow actor | octocat |
${github.identityToken.decode.payload.repository} | Extract GitHub repository | owner/repo |
${github.identityToken.decode.payload.workflow} | Extract GitHub workflow name | ci.yml |
${os.environment.K8S_POD_NAME} | Extract Kubernetes pod name from environment | my-app-pod-12345 |
${oidc.identityToken.decode.payload.user_login}_dynamic | Combined value | ci-workload_dynamic |
Configuration examples
Section titled “Configuration examples”OIDC ID Token Credential Provider
Section titled “OIDC ID Token Credential Provider”Configure dynamic claims in an OIDC ID Token Credential Provider as follows:
Subject field
Section titled “Subject field”${oidc.identityToken.decode.payload.user_login}Custom claims
Section titled “Custom claims”-
Claim Name:
workload_email -
Value:
${oidc.identityToken.decode.payload.user_email}_verified -
Claim Name:
dynamic_role -
Value:
${oidc.identityToken.decode.payload.role}
JWT-SVID Token Credential Provider
Section titled “JWT-SVID Token Credential Provider”Configure dynamic claims in a JWT-SVID Token Credential Provider for SPIFFE-compliant tokens:
Subject field (SPIFFE ID)
Section titled “Subject field (SPIFFE ID)”spiffe://your-domain/ns/${oidc.identityToken.decode.payload.namespace}/sa/${oidc.identityToken.decode.payload.service_account}Custom claims
Section titled “Custom claims”-
Claim Name:
namespace -
Value:
${oidc.identityToken.decode.payload.namespace} -
Claim Name:
cluster -
Value:
${os.environment.KUBERNETES_PROVIDER_ID}
X.509-SVID Credential Provider
Section titled “X.509-SVID Credential Provider”Configure dynamic values for the Subject and Spiffe ID fields in an X.509-SVID Credential Provider to derive each workload’s identity at issuance time from its Trust Provider attestation.
Unlike OIDC ID Tokens and JWT-SVID Tokens, X.509-SVID certificates do not carry arbitrary custom claims. Dynamic expressions on this Credential Provider therefore apply to the certificate’s identity fields:
- Spiffe ID — Resolves to the URI Subject Alternative Name on the issued certificate. This is the primary identity field for SPIFFE-aware Server Workloads.
- Subject — Resolves to the X.509 Subject Distinguished Name (DN).
SPIFFE conveys identity through the URI SAN, so this field is typically left empty.
Populate it when integrating with a Server Workload that isn’t SPIFFE-aware and instead reads the Subject DN for
authorization, or when you want descriptive metadata embedded in the certificate.
For example, you might set the Subject to
CN=payments-service,OU=billing,O=acmeso the receiving Server Workload can match on the Common Name.
SPIFFE ID field examples
Section titled “SPIFFE ID field examples”For Kubernetes workloads attested by OIDC ID Tokens:
spiffe://example.com/ns/${oidc.identityToken.decode.payload.namespace}/sa/${oidc.identityToken.decode.payload.service_account}For AWS workloads attested by AWS Role:
spiffe://example.com/aws/account/${aws.account}/role/${aws.role}The expression syntax and supported claim sources documented below apply identically to the Subject and Spiffe ID fields on an X.509-SVID Credential Provider.
Step-by-step example
Section titled “Step-by-step example”This example demonstrates extracting GitLab workload information from an OIDC token and using it in generated credentials.
-
Create an OIDC ID Token Credential Provider with dynamic claims:
- Subject:
${oidc.identityToken.decode.payload.user_login}test_dynamic - Custom Claim:
dynamic_claim1=${oidc.identityToken.decode.payload.user_email}_email
- Subject:
-
Create supporting Aembit components:
- Access Policy linking your workload to the credential provider
- Client Workload representing your OIDC token source (for example, GitLab CI job)
- Server Workload representing your target service
-
Make a credential request using your OIDC token
-
Verify the result - the generated credential contains:
- Subject:
ci-workload_test_dynamic(ifuser_loginwasci-workload) - dynamic_claim1:
ci.workload@company.com_email(ifuser_emailwasci.workload@company.com)
- Subject:
Supported claim sources
Section titled “Supported claim sources”A claim source is the identity evidence a Trust Provider validated, such as an OIDC token or a SAML 2.0 response. It can also be the process environment of Agent Proxy or Aembit CLI. The source has no effect on the Credential Provider type. An OIDC ID Token Credential Provider issues an OIDC ID Token whether its values come from an OIDC token or a SAML assertion. The following sections describe each source and how to reference it.
OIDC token claims
Section titled “OIDC token claims”Extract any claim from the incoming OIDC token’s payload:
${oidc.identityToken.decode.payload.<CLAIM_NAME>}Common GitLab CI OIDC claims
user_login- GitLab usernameuser_email- Workload’s email addressproject_path- Full project pathref- Git branch or tag referencejob_id- CI job identifier
Common GitHub Actions OIDC claims
actor- GitHub username who triggered the workflowrepository- Repository name in formatowner/reporef- Git reference (branch/tag)workflow- Workflow filename
Common Jenkins OIDC claims
-
sub- Subject claim (by default, the URL of the Jenkins job) -
iss- Jenkins instance issuer URL -
aud- Audience claim (configurable) -
`Build number (included by default)
-
Customclaims - Jenkins allows administrators to configure additional claims through “Claim templates” using build variables such as:${JOB_NAME}- Name of the Jenkins job${BUILD_NUMBER}- Build number for the job run${NODE_NAME}- Jenkins node where the job ran${BUILD_USER}- Username that triggered the build (if available)${BRANCH_NAME}- Git branch name (if applicable)- Any other Jenkins environment variables
Environment variables
Section titled “Environment variables”You can extract environment variables from Agent Proxy or Aembit CLI process for use in dynamic claims:
${os.environment.<VARIABLE_NAME>}Allowlist requirement
Section titled “Allowlist requirement”By default, Agent Proxy and Aembit CLI capture no custom environment variables.
To enable capture for dynamic claims, set the
AEMBIT_ENV_VAR_ALLOWLIST
environment variable to a comma-separated list of permitted variable names.
AEMBIT_ENV_VAR_ALLOWLIST=CORPORATE_APP_ID,WEBSITE_HOSTNAME,AWS_LAMBDA_FUNCTION_NAMEFor platform-specific guidance on injecting environment variables and the allowlist into Agent Proxy process, see Configure custom environment variables for Agent Proxy.
Always-available variables
Section titled “Always-available variables”Dynamic claims can read the following variables regardless of AEMBIT_ENV_VAR_ALLOWLIST,
provided each one exists in Agent Proxy or Aembit CLI process environment:
Common examples
Section titled “Common examples”${os.environment.K8S_POD_NAME}— Kubernetes pod name${os.environment.CLIENT_WORKLOAD_ID}— Aembit Client Workload identifier${os.environment.CORPORATE_APP_ID}— your custom application identifier (must be in the allowlist)
SAML assertion claims
Section titled “SAML assertion claims”To use these expressions, a SAMLv2 Response Trust Provider must attest the request. That Trust Provider validates the SAML 2.0 response and supplies the assertion; these expressions only read values from an assertion it has already validated. Without that attestation there is no assertion to read, and the expression resolves to no value.
Aembit exposes the following values from the validated assertion.
These expressions use SAML concepts, so there is no decode.payload step, and an OIDC expression doesn’t translate to
SAML by analogy.
| Expression | Description |
|---|---|
${saml.response.subject.nameId} | The Subject NameID, which identifies the SAML user. |
${saml.response.issuer} | The Identity Provider that issued the assertion. |
${saml.response.attributes['<name>']} | A named attribute from the assertion’s AttributeStatement. |
Aembit receives SAML 2.0 responses when users sign in through the MCP Authorization Server or the
MCP Identity Gateway.
For a policy that authenticates users through SAML, set the OIDC ID Token Credential
Provider Subject to ${saml.response.subject.nameId}.
Each SAML user then receives a credential bound to their own identity rather than one shared identity.
For the full procedure, see
Create a Credential Provider
in the MCP Authorization Server setup guide.
Adding an attribute as a custom claim
To carry an attribute into the credential, add a custom claim on the Credential Provider.
Claim Name is the name you want in the issued token, for example groups.
Value is the expression, for example ${saml.response.attributes['groups']}.
Attribute names
Copy <name> verbatim from your Identity Provider, matching its exact spelling and case.
The name can be a short name such as groups or a full URI such as
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress; both resolve the same way.
Single or double quotes around the name both work.
An attribute that carries more than one value produces one claim value per attribute value, so the
custom claim is an array.
The Subject must resolve to exactly one value; a multi-valued or empty attribute in the Subject fails closed.
Behavior when a value is missing
If a ${saml.response.*} expression can’t resolve to a value, Aembit denies the request and issues no credential rather
than an empty one.
Check the expression and the assertion before you look at network connectivity.
Keeping subjects unique
${saml.response.subject.nameId} is the normal subject expression, and a bare NameID is unique within one Identity
Provider.
If you authenticate users from more than one Identity Provider, the same NameID can appear in each.
To keep subjects distinct across Identity Providers, qualify the NameID with the issuer, for example
${saml.response.issuer}/${saml.response.subject.nameId}.
Behavior and scope
Section titled “Behavior and scope”Process boundary
Section titled “Process boundary”Aembit reads environment variables only from the Agent Proxy or Aembit CLI process environment. Variables set only in the Client Workload process aren’t visible to dynamic claims.
Behavior on missing or non-allowlisted variables
Section titled “Behavior on missing or non-allowlisted variables”When a Credential Provider references a variable that’s absent from both
AEMBIT_ENV_VAR_ALLOWLIST
and the always-available variables, Agent Proxy logs a warning
(requested env variable <name> is not in allow list) and omits the variable from the credential request.
The request still proceeds, but without that claim value.
Supported platforms
Section titled “Supported platforms”Aembit captures custom environment variables on Agent Proxy (Linux Virtual Machines, Windows Virtual Machines, and Kubernetes) and Aembit CLI (Linux and Windows Virtual Machines).
Best practices
Section titled “Best practices”The following best practices help you use dynamic claims in every Credential Provider that supports them:
Security considerations
Section titled “Security considerations”- Validate input claims - Ensure the identity evidence contains the expected values before extraction
- Limit scope - Only extract necessary claims to minimize exposure
- Review generated credentials - Use tools like jwt.io to decode and verify generated tokens
- SPIFFE compliance - For JWT-SVID tokens, ensure dynamic SPIFFE IDs follow the
spiffe://format
Template design
Section titled “Template design”- Use descriptive names - Make custom claim names clear and meaningful
- Combine values with care - When combining values, ensure the result remains valid for your target service
- Test the result - Verify dynamic claims work correctly with your specific token structure
Troubleshooting
Section titled “Troubleshooting”- Missing claims - If a referenced claim doesn’t exist in the source OIDC or JWT-SVID token, the expression may result
in an empty value.
For
${saml.response.*}expressions, Aembit denies the request instead; see SAML assertion claims. - Token format - Ensure your OIDC token follows proper formatting and contains the expected payload structure
- Permissions - Verify your OIDC provider includes the necessary claims in the token
- Environment variable not in the allowlist - If a Credential Provider references an environment variable that
isn’t listed in
AEMBIT_ENV_VAR_ALLOWLIST(and isn’t one of the always-available variables), Agent Proxy logs a warning to the effect ofrequested env variable <name> is not in allow listand omits the variable from the credential request. Add the variable name to the allowlist and restart Agent Proxy or Aembit CLI process so the claim resolves. - Environment variable missing from the process - Agent Proxy or Aembit CLI only sees variables in its own process environment. See Configure custom environment variables for Agent Proxy for platform-specific injection guidance.
Related docs
Section titled “Related docs”- Configure custom environment variables for Agent Proxy: how to inject custom variables and set the allowlist on each platform
- Edge Component environment variables reference
- Create an OIDC ID Token Credential Provider
- About the OIDC ID Token Credential Provider
- Create a JWT-SVID Token Credential Provider
- About the JWT-SVID Token Credential Provider
- SAMLv2 Response Trust Provider: the
Trust Provider that validates the SAML 2.0 response the
${saml.response.*}expressions read - Vault Dynamic Claims (for Vault-specific dynamic claims)