Customize the claims in your application's access tokens.
JWT templates allow you to customize the claims in your application’s access tokens issued by WorkOS. You can leverage core attributes of users and organizations, in addition to custom metadata you set on these objects.
JWT templates are managed in the Authentication section of the WorkOS Dashboard. Under the sessions section, choose Configure JWT Template.
JWT templates are comprised of a template string which is rendered with the user and organization context after a user successfully authenticates.
{ "urn:myapp:full_name": "{{ user.first_name || 'Someone' }} {{ user.last_name || 'Unknown' }}", "urn:myapp:email": {{ user.email }}, "urn:myapp:organization_tier": "{{ organization.metadata.tier || 'bronze' }}", "urn:myapp:user_language": "{{ user.metadata.language || 'en' }}", "urn:myapp:organization_domain": "{{ organization.domains.0.domain }}" }
{ "user": { "id": "user_01JNS7VK1HMX7CT0C6V4ZHZZNX", "metadata": { "language": "es" }, "object": "user", "created_at": "2021-01-01T00:00:00.000Z", "updated_at": "2021-01-01T00:00:00.000Z", "email": "user@example.com", "first_name": "User", "last_name": "Test", "email_verified": true, "profile_picture_url": "https://example.com/profile.jpg", "external_id": "user_123" }, "organization": { "name": "Test Organization", "id": "org_01JNS7VK1HMX7CT0C6V4ZHZZNX", "metadata": {}, "object": "organization", "created_at": "2021-01-01T00:00:00.000Z", "updated_at": "2021-01-01T00:00:00.000Z", "allow_profiles_outside_organization": false, "domains": [ { "id": "org_domain_01JNS7VK1HMX7CT0C6V4ZHZZNX", "domain": "acme.com", "object": "organization_domain", "organization_id": "org_01JNS7VK1HMX7CT0C6V4ZHZZNX", "state": "verified" }, { "id": "org_domain_01JNS7VK1HMX7CT0C6V4ZHZZNY", "domain": "example.com", "object": "organization_domain", "organization_id": "org_01JNS7VK1HMX7CT0C6V4ZHZZNX", "state": "verified" } ], "stripe_customer_id": "cus_123", "external_id": "org_123" } }
{ "urn:myapp:full_name": "User Test", "urn:myapp:email": "user@example.com", "urn:myapp:organization_tier": "bronze", "urn:myapp:user_language": "es", "urn:myapp:organization_domain": "acme.com" }
You can reference variables inside the template.
{ "user": {{ user.first_name }} }
{ "user": { "first_name": "Alice" } }
{ "user": "Alice" }
If the first value is null
or undefined, the next value in the fallback chain is used.
{ "user": {{ user.metadata.nickname || user.email }} }
{ "user": { "email": "alice@example.com" } }
{ "user": "alice@example.com" }
Strings can be used as fallback values.
{ "user": {{ user.metadata.nickname || 'Guest' }} }
{ "user": {} }
{ "user": "Guest" }
Multiple variables can be used within a single string.
{ "user": "{{ user.first_name }} {{ user.last_name }}" }
{ "user": { "first_name": "Alice", "last_name": "Smith" } }
{ "user": "Alice Smith" }
Interpolating entire objects and arrays is allowed if they are valid JSON objects. This is not allowed inside string literals and will throw a validation error.
{ "metadata": {{ user.metadata }} }
{ "user": { "metadata": { "role": "admin" } } }
{ "metadata": { "role": "admin" } }
The following keys cannot be used in templates:
iss
sub
exp
iat
nbf
jti
Any attempt to use these keys will result in a validation error.
The rendering engine trims whitespace from the beginning and end of string values.
If the template contains invalid syntax, an error will be thrown:
[ {{ user.email }} ]
iss
, sub
, exp
, etc.): These keys cannot be used in the template.
{ "iss": {{ user.email }} }
{ "user": "{{ user.metadata }}" }
||
with empty operands) or malformed expressions are not allowed.
{{ user.email && user user }} {{ user.email || || user.email }}
{{ user.id
{{ }}
is invalid.
{{}}
Template parse error: missing '}}'
Keys reserved (iss, sub, exp, etc.)
Invalid path: "unknown.variable"
JWT templates provide built-in handling for null
values to ensure access tokens only contain populated claims.
If an expression evaluates to null
, the corresponding key is removed from the final JSON output.
{ "user": {{ user.metadata.favorite_color }}, "organization_tier": {{ organization.metadata.tier }} }
{ "user": { "metadata": {} }, "organization": { "metadata": { "tier": "bronze" } } }
{ "organization_tier": "bronze" }
If a null
value appears in a string concatenation, it is replaced with an empty string (""
) instead of being removed.
{ "user": "{{ user.first_name }} {{ user.last_name }}" }
{ "user": { "first_name": "Alice", "last_name": null } }
{ "organization_tier": "bronze" }
The ||
operator can be used to provide a fallback value when an expression evaluates to null
.
{ "external_id": {{ user.external_id || 'unknown' }} }
{ "user": { "external_id": null } }
{ "external_id": "unknown" }