Skip to content
Open
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions docs/embeddable-uis/element-login.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ npm install @permitio/permit-js
| `headers` | Header | The authentication headers `permit.elements.login()` sends to `loginUrl`. |
| `userJwt` | `frontendOnly` | The signed-in user's JWT. Permit verifies it against the environment JWKS. |
| `envId` | `frontendOnly` | The ID of the Permit environment. The **Generate Code** dialog in the Elements screen shows it in the iframe `src`. |
| `userKeyClaim` | Optional, `frontendOnly` only | The JWT claim that holds the user's Permit key, when the key is not in `sub`. |
| `userKeyClaim` | Optional, `frontendOnly` only | Deprecated: [set the user key claim on the environment](/how-to/enforce-permissions/url-mapping/configuring-jwks#user-key-claim) instead. If you pass it, it must be `sub` or the environment's user key claim. |
| `elementIframeUrl` | Private browsing | The exact `src` of the element iframe. |

### Log in with your method \{#use-the-login-method}
Expand Down Expand Up @@ -517,7 +517,7 @@ permit.elements

<TabItem value="frontendonly" label="FrontendOnly">

Set `loginMethod` to `LoginMethod.frontendOnly`, and pass the user's JWT, the tenant key, and the environment ID. The environment must have a JWKS configured, and the user's key in Permit must match the JWT `sub` claim or the claim you pass as `userKeyClaim`. See [Embed Permit Elements](/embeddable-uis/embedding-elements) for the full `frontendOnly` walkthrough.
Set `loginMethod` to `LoginMethod.frontendOnly`, and pass the user's JWT, the tenant key, and the environment ID. The environment must have a JWKS configured, and the user's key in Permit must match the JWT's `sub` claim, or the claim [set as the environment's user key claim](/how-to/enforce-permissions/url-mapping/configuring-jwks#user-key-claim). See [Embed Permit Elements](/embeddable-uis/embedding-elements) for the full `frontendOnly` walkthrough.

```ts
import permit, { LoginMethod } from "@permitio/permit-js";
Expand Down
4 changes: 2 additions & 2 deletions docs/embeddable-uis/embedding-elements.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The `frontendOnly` login method sends the user's JWT to Permit, and Permit verif

![JWKS Config tab in the Permit dashboard settings, with a JWKS pasted in the editor](/img/elements/user-management/ConfigureJwks.png)

Check that each user's key in Permit matches the `sub` claim of the user's JWT. The **Users** page in the Permit dashboard shows user keys. To read the `sub` claim, decode a JWT with a tool such as [jwt.io](https://jwt.io/). If the user key is in a different claim, pass that claim's name as `userKeyClaim` when you log the user in.
Check that each user's key in Permit matches the `sub` claim of the user's JWT. The **Users** page in the Permit dashboard shows user keys. To read the `sub` claim, decode a JWT with a tool such as [jwt.io](https://jwt.io/). If the user key is in a different claim, [set that claim as the environment's user key claim](/how-to/enforce-permissions/url-mapping/configuring-jwks#user-key-claim).

For JWKS options, including a JWKS URL, see [Configure JWKS](/how-to/enforce-permissions/url-mapping/configuring-jwks).

Expand Down Expand Up @@ -102,7 +102,7 @@ Call `permit.elements.login()` after your identity provider signs the user in, a
| `userJwt` | The signed-in user's JWT. |
| `tenant` | The key of the tenant the element shows. The user must have a role in this tenant. |
| `envId` | The environment ID from the iframe `src`, or from the [List Environments API](https://api.permit.io/v2/redoc#tag/Environments/operation/list_environments). The environment must have the JWKS from step 1. |
| `userKeyClaim` | Optional. The JWT claim that holds the user key, when the key is not in `sub`. |
| `userKeyClaim` | Optional and deprecated: [set the user key claim on the environment](/how-to/enforce-permissions/url-mapping/configuring-jwks#user-key-claim) instead. If you pass it, it must be `sub` or the environment's user key claim. |

Replace `<YOUR_USER_JWT>`, `<YOUR_TENANT_KEY>`, and `<YOUR_ENV_ID>` with your values:

Expand Down
21 changes: 21 additions & 0 deletions docs/how-to/enforce-permissions/url-mapping/configuring-jwks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,27 @@ To confirm that the JWKS contains the key for your tokens, compare the `kid` in

To configure a JWKS without the dashboard, update the environment with `PATCH /v2/projects/{proj_id}/envs/{env_id}` and set the `jwks` field. The `jwks` field accepts a `jwks` object with a `keys` array, or a `url`, and an optional `ttl`: the time in seconds Permit caches the JWKS (default `600`). See the [Environments API reference](https://api.permit.io/v2/redoc#tag/Environments).

## Set the user key claim \{#user-key-claim}

When a user logs in to Permit Elements with `LoginMethod.frontendOnly`, or approves an Elements invite with their JWT, Permit reads the user's Permit key from one claim of the JWT. That claim is `sub` unless you set another one on the environment. If your identity provider puts the user key in a different claim, set `user_key_claim` in the `jwks` field:

```bash
curl -X PATCH 'https://api.permit.io/v2/projects/{proj_id}/envs/{env_id}' \
-H 'authorization: Bearer API_SECRET_KEY' \
-H 'Content-Type: application/json' \
-d '{"jwks": {"url": "<YOUR_JWKS_URL>", "user_key_claim": "<CLAIM_NAME>"}}'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW] Say that the jwks object replaces the stored configuration

Problem: A PATCH replaces the stored jwks object with the one in the request. Only issuer, audience and user_key_claim are kept when the request leaves them out. Readers who copy this example may not expect three things:

  • an environment set up with inline jwks.keys has to send its keys again (the example shows only url);
  • a custom ttl goes back to 600 unless it is sent again;
  • a jwks object that carries only user_key_claim is rejected with 422. That includes the "user_key_claim": null on line 94, which also needs the url or jwks.keys.

Suggestion: Add a sentence after the example, and point line 94 at it:

The `jwks` object you send replaces the stored one, so include your current `url` or `jwks.keys`, and your `ttl` if you changed it. Permit keeps the stored `issuer`, `audience` and `user_key_claim` when you leave them out.

At line 94, for example: "To go back to sub, send the same configuration with "user_key_claim": null."

Introduced in bb3e455

```

- **Name only a claim your identity provider sets.** Permit refuses claims that the user or the client can set, such as an OIDC `nonce`, `name` or `aud`. A custom claim filled from profile data the user can edit is just as unsafe.
- **The value must be a non-empty string or an integer.** Permit reads an integer as its decimal string.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW] Say this rule is about the claim's value in the token

Problem: "The value" can be read as the value of the user_key_claim setting. The setting only takes a string: the claim's name. The string-or-integer rule applies to the value the token carries in that claim.

Suggestion:

- **The claim's value in the token must be a non-empty string or an integer.** Permit reads an integer as its decimal string.

Introduced in bb3e455

- **`email` needs a verified email.** Permit accepts the `email` claim only from a token whose `email_verified` claim is the JSON boolean `true`. Tokens without `email_verified`, such as Entra ID's, or with the string `"true"` can't use it. A user keyed by email changes key when their email changes at the identity provider.
- **On a shared identity provider, also set `issuer` and `audience`.** For a JWKS URL on Entra ID, Google, Apple, Salesforce, LinkedIn or Facebook, a request that sets or changes `user_key_claim` needs `issuer` and `audience` in the same configuration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW] Say what issuer and audience are and where they go

Problem: No other docs page mentions the issuer and audience fields. Readers on Entra ID or Google who hit this rule aren't told three things:

  • the fields go in the same jwks object;
  • issuer is the iss their tokens carry, compared exactly (a list is accepted);
  • audience is a value of the tokens' aud.

While user_key_claim is set on one of these URLs, an update that changes or clears issuer or audience must also keep both set.

Suggestion: Name the fields and show them in a request body, for example:

- **On a shared identity provider, also set `issuer` and `audience`.** For a JWKS URL on Entra ID, Google, Apple, Salesforce, LinkedIn or Facebook, a request that sets or changes `user_key_claim` needs both in the same `jwks` object: `issuer` is the `iss` your tokens carry, and `audience` is a value of their `aud`. For example: `{"jwks": {"url": "<YOUR_JWKS_URL>", "issuer": "<YOUR_ISSUER>", "audience": "<YOUR_AUDIENCE>", "user_key_claim": "<CLAIM_NAME>"}}`. While `user_key_claim` is set, neither can be cleared.

Introduced in bb3e455

- **Changing the claim changes which user each token logs in as.** Users whose Permit key matches the old claim's value don't match the new one.

To go back to `sub`, send `"user_key_claim": null`. Removing the whole configuration with `"jwks": null` removes it as well.

`permit.elements.login()` and the invite approval request also accept a `userKeyClaim` (`user_key_claim`) parameter. Set the claim on the environment instead. If you pass the parameter, it must be `sub` or the environment's `user_key_claim`. When the environment sets `user_key_claim`, Permit rejects any other value.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Drop the conditional last sentence

Problem: The sentence before it already gives the rule for this parameter: if you pass it, it must be sub or the environment's user_key_claim. The API reference for the deprecated parameter states the same rule with no condition. The last sentence restates it but makes it depend on the environment setting, so this page and the API reference no longer describe the same contract.

Suggestion: Delete "When the environment sets user_key_claim, Permit rejects any other value." If the paragraph should still say what happens, fold it into the sentence before, with no condition:

`permit.elements.login()` and the invite approval request also accept a `userKeyClaim` (`user_key_claim`) parameter. Set the claim on the environment instead. If you pass the parameter, it must be `sub` or the environment's `user_key_claim`, or Permit rejects the request.

Introduced in bb3e455


## Next steps

- [Embed Permit Elements in your application](/embeddable-uis/embedding-elements)
Expand Down
2 changes: 1 addition & 1 deletion docs/overview/access-requests-and-approvals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ A JSON Web Key Set (JWKS) is the set of public keys that verify the JWTs your au

1. In the Permit dashboard, open **Settings** and select **JWKS Config**.
2. Paste your JWKS for the environment and click **Save**.
3. Confirm that each user's key in Permit matches the `sub` claim of the user's JWT. If the key is in another claim, pass that claim name as `userKeyClaim` when you log the user in (step 5).
3. Confirm that each user's key in Permit matches the `sub` claim of the user's JWT. If the key is in another claim, [set that claim as the environment's user key claim](/how-to/enforce-permissions/url-mapping/configuring-jwks#user-key-claim).

See [Configuring JWKS for your environment](/embeddable-uis/embedding-elements#configuring-jwks-for-your-environment).

Expand Down
Loading