Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions docs/backend-requests/resources/session-tokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Read more about Clerk session tokens and how they work in [the guide on how Cler
> [!IMPORTANT]
> You are reading about version 2 of Clerk's session token claims. To read about version 1, select the respective tab above.

### Default claims

Every generated token has default claims that cannot be overridden by templates. Clerk's default claims include:

| Claim | Abbreviation expanded | Description | Example |
Expand All @@ -28,10 +30,12 @@ Read more about Clerk session tokens and how they work in [the guide on how Cler
| `sid` | session ID | The ID of the current session. | `sess_123` |
| `sub` | subject | The ID of the current user of the session. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2) for more information. | `user_123` |
| `v` | version | The version number of the session token. | `2` |
| `pla` | plan | A comma-separated list of the plans that are active. Each entry is in the format `scope:planslug`, where `scope` can be `u` or `o` representing user or org-level plans, respectively. Will always have either one entry (if no org is active) or two entries (if a user and org are both active). | `u:free,o:pro` |
| `fea` | features | A list of enabled features and their scope. The scope can either be `o` for org-level features, `u` for user-level features, or `uo` for both. | `o:dashboard,o:impersonation` |
| `pla` | plan | A comma-separated list of the plans that are active. Each entry is in the format `scope:planslug`, where `scope` can be `u` or `o` representing user or org-level plans, respectively. Will always have only one entry, which will have `u:` prefix if no org is active or `o:` prefix if an org is active. | `u:free`,`o:pro` |
| `fea` | features | A list of enabled features and their scope. The scope can either be `o` for org-level features or `u` for user-level features. Same as the `pla` claim, the scopes for all features with start with `o:` if there is an active org, or `u:` if there is not. | `o:dashboard,o:impersonation` |
| `sts` | session status | The status of the current session | `pending` |

### Organization claim

The **`o` claim**, or organization claim, is only included if the user is part of an [organization](/docs/organizations/overview) and that organization is [active](/docs/organizations/overview#active-organization). Its value is an object that contains the following properties:

| Claim | Abbreviation expanded | Description | Example |
Expand All @@ -40,12 +44,29 @@ Read more about Clerk session tokens and how they work in [the guide on how Cler
| `slg` | slug | The slug of the organization. | `org-slug` |
| `rol` | role | The role of the user in the organization, without the `org:` prefix. | `admin` |
| `per` | permissions | The names of the permissions the user has in the organization. | `read,manage` |
| `fpm` | feature-permission map | The mapping of features with permissions, where the value of the integer, when converted to binary, represents a bitmask where each bit's position corresponds to a permission in the `o.per` list, and where `0` = `not-allowed` and `1` = `allowed`. | `3,2` |
| `fpm` | feature-permission map | The mapping of features with permissions. See below for details for how this claim value is constructed. | `3,2` |

> [!WARNING]
> The organization claims above are intentionally designed to be as compact as possible to keep JWT tokens small.
> As a result, they can be difficult to decode manually. We strongly recommend using one of our SDKs that support API version [2025-04-10](/docs/versioning/available-versions#2025-04-10) to handle decoding reliably.

#### How to decode

For those that need to decode the `o.fpm` claim manually, here is how the claim value is computed.
The value is a list of comma-separated integers where the position of the integer corresponds to a feature in the same position in the `fea` claim.
Each integer, when converted to binary, represents a bitmask where each bit's position corresponds to a permission in the `o.per` list, where `0` = `not-allowed` and `1` = `allowed`.

#### Example

Consider a user with an active organization has role `admin`. This role has the following feature permissions: `dashboard:read`, `dashboard:manage`, `teams:read`.
The `fea` claim has value `o:dashboard,o:teams`, and the `o.per` claim has value `manage,read`.

The `o.fpm` claim has value `3,2`.
The first integer `3` repesents the feature-permission mapping for the `dashboard` feature. Since `3` is `11` in binary, both permissions are allowed (`dashboard:read` and `dashboard:manage`).
The second integer `2` represents the feature-permission mapping for the `teams` feature. Since `2` is `10` in binary, the _second_ permission is allowed (`teams:read`).

### Actor claim

The **`act` (actor) claim** is only included if the user is [impersonating](/docs/users/user-impersonation) another user. It's value is an object that contains the following properties:

| Claim | Abbreviation expanded | Description | Example |
Expand Down