<@U04UQ68083H> how to add traits to the payload of...
# ory-copilot
f
@chilly-king-10285 how to add traits to the payload of jwt ?
b
A message from kapa.ai
To add identity traits to the payload of a JWT in Ory, you need to customize the JWT claims using a Jsonnet claims mapper when configuring your JWT tokenizer template. The claims mapper allows you to include any part of the Ory session, including identity traits, in the JWT payload. Here’s how you can do it: 1. Create a Jsonnet claims mapper that adds the traits to the JWT claims. For example:
Copy code
jsonnet local claims = std.extVar('claims'); local session = std.extVar('session');  {   claims: {     // Default claims     iss: claims.iss,     exp: claims.exp,     sub: claims.sub,     // Add traits from the session     traits: session.identity.traits,     // You can add other custom claims as needed   } }
2. Configure your Ory project to use this claims mapper in your JWT tokenizer template. You’ll need to base64-encode the Jsonnet file and reference it in your configuration:
Copy code
yaml session:   whoami:     tokenizer:       templates:         jwt_template_1:           jwks_url: base64://... # Your JSON Web Key Set           claims_mapper_url: base64://... # Your base64-encoded Jsonnet           ttl: 10m
3. Issue a JWT using this template. The resulting JWT will now include the
traits
field in its payload, containing the identity traits. For more details and a step-by-step example, see the official documentation on [converting Ory sessions to JWTs](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-templates) and [customizing JWT claims with Jsonnet](https://www.ory.sh/docs/kratos/reference/jsonnet) in Ory Network. > Note: The
sub
claim (subject) is always set to the Ory Session's
IdentityID
and cannot be overwritten. All other claims can be customized as shown above. If you need to include only specific traits, adjust the Jsonnet accordingly:
Copy code
jsonnet traits: {   email: session.identity.traits.email,   lang: session.identity.traits.lang, }
This approach gives you full control over which traits are included in the JWT payload and how they are structured [Convert Ory Sessions to JSON Web Tokens](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-templates).
f
@chilly-king-10285 where to add Create a Jsonnet claims mapper
b
A message from kapa.ai
You add the Jsonnet claims mapper as part of your JWT tokenizer template configuration in your Ory project's identity config. Specifically, you provide the claims mapper as a base64-encoded file (or a URL) in the
claims_mapper_url
field under your JWT template. Here’s where and how to add it: 1. Create your Jsonnet claims mapper file (e.g.,
claims.jsonnet
). 2. Base64-encode the file. 3. Add the base64-encoded string to your identity config under the
session.whoami.tokenizer.templates.<your_template>.claims_mapper_url
field. Example configuration snippet:
Copy code
yaml session:   whoami:     tokenizer:       templates:         jwt_template_1:           jwks_url: base64://... # Your JSON Web Key Set           claims_mapper_url: <base64://YOUR_BASE64_ENCODED_JSONNET_HERE>           ttl: 10m
This configuration is part of your Ory Identities config file, which you can update using the Ory CLI. For a full example and step-by-step instructions, see the [Ory documentation on JWT templates](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-templates) and [session-to-JWT conversion](https://www.ory.sh/docs/identities/session-to-jwt-cors) in Ory Network.
f
@chilly-king-10285 i have this function(ctx) { "session": { identity: { id: ctx.identity.id, traits: { email: ctx.identity.traits.email, username: ctx.identity.traits.username, firstName: ctx.identity.traits.firstName, lastName: ctx.identity.traits.lastName, fullname: ctx.identity.traits.fullname, departmentId: ctx.identity.traits.departmentId, }, }, amr: ctx.session.amr, auth_time: ctx.session.authenticated_at, }, "iss": "https://login.alpha.qaap.io", "sub": ctx.identity.id, }
b
A message from kapa.ai
The code you provided is a JavaScript-like function, but Ory expects claims mapping to be done using [Jsonnet](https://jsonnet.org/), not JavaScript. The claims mapper for JWTs in Ory should be a Jsonnet file, which is then base64-encoded and referenced in your Ory configuration under
claims_mapper_url
in the JWT tokenizer template. Here’s how your mapping would look in Jsonnet, based on your example:
Copy code
jsonnet local session = std.extVar('session');  {   claims: {     session: {       identity: {         id: session.identity.id,         traits: {           email: session.identity.traits.email,           username: session.identity.traits.username,           firstName: session.identity.traits.firstName,           lastName: session.identity.traits.lastName,           fullname: session.identity.traits.fullname,           departmentId: session.identity.traits.departmentId,         },       },       amr: session.amr,       auth_time: session.authenticated_at,     },     iss: "<https://login.alpha.qaap.io>",     sub: session.identity.id,   } }
How to use this: 1. Save this Jsonnet code to a file (e.g.,
claims.jsonnet
). 2. Base64-encode the file. 3. Add the base64-encoded string to your Ory identity config under
claims_mapper_url
in your JWT template, as described in the documentation:
Copy code
yaml session:   whoami:     tokenizer:       templates:         jwt_template_1:           jwks_url: base64://... # Your JSON Web Key Set           claims_mapper_url: <base64://YOUR_BASE64_ENCODED_JSONNET_HERE>           ttl: 10m
For more details, see the official documentation on [JWT templates and claims mapping](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-templates) and [Jsonnet reference](https://www.ory.sh/docs/kratos/reference/jsonnet). > Note: The variables available in Jsonnet are provided via
std.extVar('session')
and
std.extVar('claims')
, not via a
ctx
object as in your JavaScript example. If you need to access traits, use
session.identity.traits
as shown above. If you need further help converting your mapping or integrating it, let me know!
f
@chilly-king-10285 this is hydra or kratos config ?
b
A message from kapa.ai
The configuration and claims mapping you are referring to is for Ory Kratos, specifically for customizing the payload of JSON Web Tokens (JWTs) generated from Ory Sessions. This is done using a Jsonnet claims mapper in the Kratos (or Ory Identities) configuration, as described in the official documentation on [converting Ory sessions to JWTs](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-templates). Ory Hydra, on the other hand, is an OAuth2 and OpenID Connect provider and does not use this Jsonnet-based claims mapping for JWTs in the same way. The Jsonnet claims mapper and the
session.whoami.tokenizer.templates
configuration are specific to Ory Kratos/Ory Identities. If you are working with JWT claims mapping using Jsonnet and the
claims_mapper_url
, you are configuring Ory Kratos, not Ory Hydra. [Convert Ory Sessions to JSON Web Tokens](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-templates)
f
@chilly-king-10285 how to map traits
b
A message from kapa.ai
To map traits from a social sign-in provider or session into the Ory identity, you use a Jsonnet data mapper. This Jsonnet code is referenced in your Ory configuration and is responsible for transforming the incoming claims into the structure required by your identity schema. ### Example: Mapping Traits with Jsonnet Here’s a basic example of mapping the
email
claim to the
email
trait in your identity schema:
Copy code
jsonnet local claims = std.extVar('claims');  {   identity: {     traits: {       [if 'email' in claims then 'email' else null]: claims.email,     },   }, }
This will set the
email
trait if the claim exists. You can map additional traits as needed, for example:
Copy code
jsonnet local claims = std.extVar('claims');  {   identity: {     traits: {       email: claims.email,       first_name: claims.given_name,       last_name: claims.family_name,     },   }, }
You can also set metadata fields if you want to store additional information:
Copy code
jsonnet local claims = std.extVar('claims');  {   identity: {     traits: {       email: claims.email,     },     metadata_public: {       github_username: claims.username,     },   }, }
The structure of the
claims
object depends on the social provider and the scopes you request. If a claim is not present, you can use conditional logic to handle it gracefully. For more details and advanced examples, see the [Ory documentation on data mapping](https://www.ory.sh/docs/kratos/social-signin/data-mapping#write-a-jsonnet-data-mapper) and [reference for Jsonnet mapping](https://www.ory.sh/docs/kratos/reference/jsonnet).
f
@chilly-king-10285 how to map these ? { "$id": "identity.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Person", "type": "object", "properties": { "traits": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "title": "E-Mail", "minLength": 3, "ory.sh/kratos": { "credentials": { "password": { "identifier": true }, "totp": { "account_name": true } }, "verification": { "via": "email" }, "recovery": { "via": "email" } } }, "username": { "type": "string", "title": "Username", "minLength": 3, "ory.sh/kratos": { "credentials": { "password": { "identifier": true } } } }, "firstName": { "title": "First Name", "type": "string" }, "lastName": { "title": "Last Name", "type": "string" }, "fullname": { "title": "Full Name", "type": "string" }, "departmentId": { "title": "Department ID", "type": "string" } }, "required": ["username"], "additionalProperties": false } } }
b
A message from kapa.ai
To map the traits defined in your identity schema (
email
,
username
,
firstName
,
lastName
,
fullname
,
departmentId
) using Ory, you need to create a Jsonnet data mapper that assigns values from the incoming claims to these traits. The mapping depends on the data provided by your social sign-in provider or OIDC claims. Here is an example Jsonnet data mapper that maps these fields, assuming the claims object contains the corresponding keys:
Copy code
jsonnet local claims = std.extVar('claims');  {   identity: {     traits: {       [if 'email' in claims then 'email' else null]: claims.email,       [if 'username' in claims then 'username' else null]: claims.username,       [if 'firstName' in claims then 'firstName' else null]: claims.firstName,       [if 'lastName' in claims then 'lastName' else null]: claims.lastName,       [if 'fullname' in claims then 'fullname' else null]: claims.fullname,       [if 'departmentId' in claims then 'departmentId' else null]: claims.departmentId,     },   }, }
How this works: - Each trait is conditionally set if the corresponding claim exists in the incoming data. - This approach ensures that only available data is mapped, and missing fields will not cause errors during mapping, which is recommended in the [Ory documentation](https://www.ory.sh/docs/kratos/reference/jsonnet#optionality). Important notes: - If a required trait (like
username
in your schema) is missing from the claims, Ory will prompt the user to fill it in during registration, as described in the [data mapping documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping#write-a-jsonnet-data-mapper). - You may need to adjust the claim keys if your provider uses different names (e.g.,
given_name
instead of
firstName
). In that case, map accordingly. For more details and examples, see the [Ory data mapping documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping#write-a-jsonnet-data-mapper).
f
@chilly-king-10285 now how to use claims.jsonnet
b
A message from kapa.ai
To use your
claims.jsonnet
file for mapping traits in Ory, you need to reference it in your Ory Identities (Kratos) configuration as a data mapper for your social sign-in or OIDC provider. Here’s how you do it, based on the official documentation: 1. Encode your Jsonnet file Encode your
claims.jsonnet
file in Base64:
Copy code
cat claims.jsonnet | base64
2. Add the Base64-encoded Jsonnet to your provider config In your Ory Identities configuration (for example, in
identity-config.yaml
), add or update your provider configuration to include the
mapper_url
field with your Base64-encoded Jsonnet. Here’s an example for a generic OIDC provider:
Copy code
yaml    selfservice:      methods:        oidc:          config:            providers:              - id: generic                provider: generic                client_id: ... # Your Client ID                client_secret: ... # Your Client Secret                issuer_url: ... # Your Issuer URL                mapper_url: "<base64://YOUR_BASE64_ENCODED_JSONNET_HERE>"                scope:                  - email                  - profile          enabled: true
You can also use a URL to the Jsonnet file if it is hosted somewhere accessible to Ory Network. 3. Update your Ory Identities configuration Use the Ory CLI to update your project configuration:
Copy code
ory update identity-config --project <project-id> --workspace <workspace-id> --file identity-config.yaml
This process is the same for both Ory Network and self-hosted Ory Kratos. The key is to set the
mapper_url
for your provider to point to your Jsonnet data mapper, either as a Base64 string or a URL. For more details, see the [official Ory documentation on data mapping](https://www.ory.sh/docs/kratos/social-signin/data-mapping#write-a-jsonnet-data-mapper) and [generic provider setup](https://www.ory.sh/docs/kratos/social-signin/generic).