Repository navigation
docs: Elements reads the user key from the environment's user key claim (PER-17237) - #686
CarlosMion wants to merge 1 commit into
Conversation
Document `user_key_claim` in the environment's JWKS configuration: the claim Elements login and JWT invite approval read the Permit user key from (`sub` by default), the rules for choosing it, and how to clear it. Mark the `userKeyClaim` login parameter deprecated and point the Elements pages at the environment setting.
✅ Deploy Preview for permitio-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
zeevmoney
left a comment
There was a problem hiding this comment.
Changes requested — 1 HIGH, 3 LOW.
Blocking:
- HIGH
docs/how-to/enforce-permissions/url-mapping/configuring-jwks.mdx:96— drop the conditional last sentence, so the paragraph keeps the contract the API reference states
Non-blocking:
- LOW
docs/how-to/enforce-permissions/url-mapping/configuring-jwks.mdx:85— say that thejwksobject replaces the stored configuration - LOW
docs/how-to/enforce-permissions/url-mapping/configuring-jwks.mdx:89— say the string-or-integer rule is about the claim's value in the token - LOW
docs/how-to/enforce-permissions/url-mapping/configuring-jwks.mdx:91— say whatissuerandaudienceare and where they go
Details are in the inline comments on each line.
|
|
||
| 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. |
There was a problem hiding this comment.
[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
| 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>"}}' |
There was a problem hiding this comment.
[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.keyshas to send its keys again (the example shows onlyurl); - a custom
ttlgoes back to600unless it is sent again; - a
jwksobject that carries onlyuser_key_claimis rejected with 422. That includes the"user_key_claim": nullon line 94, which also needs theurlorjwks.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. |
There was a problem hiding this comment.
[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
| - **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. | ||
| - **`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. |
There was a problem hiding this comment.
[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
jwksobject; issueris theisstheir tokens carry, compared exactly (a list is accepted);audienceis 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
Summary
user_key_claimin an environment's JWKS configuration: the JWT claim that Elements login (LoginMethod.frontendOnly) and JWT invite approval read the Permit user key from. It issubunless set.emailonly with a booleanemail_verified: true,issuerandaudiencerequired alongside it on shared identity providers, and the re-keying effect of changing it. Shows how to clear it.userKeyClaimlogin parameter deprecated, and points the Elements pages at the environment setting instead.PER-17237.
Changes
docs/how-to/enforce-permissions/url-mapping/configuring-jwks.mdx#user-key-claim): the API request, the rules, clearing it, and how theuserKeyClaimparameter relates to it.docs/embeddable-uis/element-login.mdxuserKeyClaimrow: deprecated, links to the new section. ThefrontendOnlytab's key-matching sentence names the environment's user key claim.docs/embeddable-uis/embedding-elements.mdxuserKeyClaimrow point at the environment setting.docs/overview/access-requests-and-approvals.mdxThe section documents the API only. The dashboard's JWKS dialog gains a matching field in a separate change, and the page can describe it once that field is live.
🤖 Generated with Claude Code