> ## Documentation Index
> Fetch the complete documentation index at: https://stytch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Add custom claims

> Encode additional information into your session JWTs using custom claims.

## Use case

* **Store or pass user information:** Pass temporary session state or user metadata to your application.
* **Integrate with 3rd-party services:** Integrate with providers that support JWT-based authentication.
* **Implement custom authorization logic:** Use custom claim templates to pass RBAC information to sessions.

***

## Add custom claims to a session

Include the `session_custom_claims` argument on any authenticate method to add custom claims to a session. This argument takes in an arbitrary JSON object—which may be represented as a `map`, `dictionary`, or object:

```python theme={null}
# initial claims object {}

stytch.session.authenticate(token, session_custom_claims={"key_1": 1, "key_2": 2})
# current claims object {"key_1": 1, "key_2": 2}

stytch.session.authenticate(token, session_custom_claims={"key_1": 9})
# resulting claims object {"key_1": 9, "key_2": 2}
```

### Remove claims

Supply a `null` value to delete a key:

```python theme={null}
# current claims object {"key_1": 1, "key_2": 2}

stytch.session.authenticate(token, session_custom_claims={"key_1": null})
# resulting claims object {"key_2": 2}
```

<Accordion title="Using nested claim objects">
  If the value of a custom claim is a JSON object, the nested values can be updated or deleted using the same methods as above:

  ```python theme={null}
  sessions.authenticate(token, session_custom_claims={
      "b": null,
      "c": 3.5,
      "e": {
          "nested1": "val1",
          "nested2": "val2"
      }
  })
  # resulting claims object
  # {
  #    "c": 3.5,
  #    "d": 4,
  #    "e": {
  #        "nested1": "val1",
  #        "nested2": "val2"
  #    }
  # }

  stytch.session.authenticate(token, session_custom_claims={
      "e": {
          "nested1": nil,
          "nested3": "val3"
      }
  )
  # resulting claims object
  # {
  #     "c": 3.5,
  #     "d": 4,
  #     "e": {
  #         "nested2": "val2",
  #         "nested3": "val3"
  #     }
  # }
  ```
</Accordion>

***

## Custom claim templates

Use [custom claim templates](https://stytch.com/dashboard/custom-claim-templates) to add the same set of claims to **every** session.

* The JSON object output for a particular user will be used as the initial set of custom claims for all of that user's sessions.
* Claims from templates can still be added, updated, or deleted by passing in a `session_custom_claims` argument in an API request.
* Updates to the custom claim template or user metadata propagate to existing sessions the next time a JWT is minted.
* Previously minted JWTs are immutable and cannot be updated.

### Markup syntax

Custom claim template markup language uses `{{ variable }}` syntax to denote information that should be passed in at runtime.

### User metadata

Use dot notation to access nested fields when handling User metadata. For example, `{{ user.trusted_metadata.subscription.level }}` accesses the `level` field of the `subscription` object in the `trusted_metadata` on a User object.

### User RBAC values

The variable `{{ user.rbac.roles }}` is evaluated as an array of all role IDs assigned to the user, e.g. `["stytch_user", "editor", "support_admin"]`.

The variable `{{ user.rbac.$RESOURCE_ID.actions }}` is evaluated as an array of all actions the user can perform on the specific resources. For example, `{{ user.rbac.documents.actions }}` might be evaluated as `["create", "read", "delete"]`.

### List of supported template variables

* `{{ user.external_id }}`
* `{{ user.user_id }}`
* `{{ user.full_name }}`
* `{{ user.rbac.roles }}`
* `{{ user.rbac.$RESOURCE_ID.actions }}`
* `{{ user.trusted_metadata.$PATH }}`

<Accordion title="Example">
  The template:

  ```json theme={null}
  {
    "https://hasura.io/jwt/claims": {
      "x-hasura-default-role": "reader",
      "x-hasura-allowed-roles": {{ user.rbac.roles }},
      "x-hasura-user-id": {{ user.user_id }},
      "x-hasura-custom-key": {{ user.trusted_metadata.custom_key }},
    }
  }
  ```

  could be combined with the user's information:

  ```json theme={null}
  {
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
    "trusted_metadata": {
      "custom_key": "custom-value"
    }
  }
  ```

  to produce the final set of custom claims:

  ```json theme={null}
  {
    "https://hasura.io/jwt/claims": {
      "x-hasura-default-role": "reader",
      "x-hasura-allowed-roles": ["admin", "reader"],
      "x-hasura-user-id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
      "x-hasura-custom-key": "custom-value",
    }
  }
  ```
</Accordion>

***

## Limitations

Both API-driven custom claims and custom claim templates share these limitations:

### List of reserved claims

These claims are reserved and will result in an error if set:

* `iss`
* `sub`
* `aud`
* `exp`
* `nbf`
* `iat`
* `jti`
* `https://stytch.com/*`

### Size limit

Total claims size cannot exceed 4kb.

### JWT immutability

A JWT cannot be modified once it is minted. You must authenticate again to update claims.
