Skip to content

Commit 96bf4ce

Browse files
authored
docs: handle user permission change (#1319)
1 parent f26a920 commit 96bf4ce

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
### Optional: Handle user permission change \{#optional-handle-user-permission-change}
2+
3+
User permissions can change at any time. Because Logto issues JWTs for RBAC, permission updates only appear in newly issued tokens, and never modify existing JWTs.
4+
5+
:::info Scope subset rule
6+
An access token can only include scopes that were requested in the original OAuth authorization flow.
7+
Even if a user gains new permissions, the token issued later can only contain a subset of the originally requested scopes.
8+
To access newly granted scopes that were not part of the initial request, the client must run a new authorization flow.
9+
:::
10+
11+
#### Downscoped permissions
12+
13+
When a user loses permissions:
14+
15+
- Newly issued tokens immediately reflect the reduced scopes.
16+
- Existing JWTs keep the old scopes until they expire.
17+
- Your API should always validate scopes and rely on short token lifetimes.
18+
19+
If you need faster reactions, implement your own signal that tells clients to refresh their tokens.
20+
21+
#### Enlarged permissions
22+
23+
{props.type === "global" && <p>For global API resources, when a user gains permissions, enlarged permissions will NOT show up through refresh. The client must perform a new OAuth authorization flow to obtain a token that includes the new scopes. This can happen silently if the user has an active Logto session.</p>}
24+
25+
{props.type === "organization" && <p>For organization tokens, when a user gains permissions, enlarged permissions will show up on the next issuance (refresh or token request). A new token is still required, but no full re-auth is needed unless the new scopes exceed the original request set.</p>}
26+
27+
#### Recommendations
28+
29+
- Validate scopes in your API on every call.
30+
- Keep token expiration short.
31+
- Add optional notifications if you need immediate permission-change propagation.

docs/authorization/global-api-resources.mdx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import illustration from '@site/docs/authorization/assets/rbac-global-api-resour
66
import AuthorizationRequestExample from '@site/docs/authorization/fragments/AuthorizationRequestExample';
77
import ClientCredentialsRequestExample from '@site/docs/authorization/fragments/ClientCredentialsRequestExample';
88
import TokenRequestExample from '@site/docs/authorization/fragments/TokenRequestExample';
9+
import HandleUserPermissionChange from '@site/docs/authorization/fragments/_handle-user-permission-change.mdx';
910
import TabItem from '@theme/TabItem';
1011
import Tabs from '@theme/Tabs';
1112

@@ -192,11 +193,7 @@ When your API receives a request with a Logto-issued access token, you should:
192193

193194
For step-by-step and language-specific guides, see [How to validate access tokens](/authorization/validate-access-tokens).
194195

195-
### Optional: Handle user permission change \{#optional-handle-user-permission-change}
196-
197-
:::info
198-
👷 Work in progress. 🚧
199-
:::
196+
<HandleUserPermissionChange type="global" />
200197

201198
## Best practices and security tips \{#best-practices-and-security-tips}
202199

docs/authorization/organization-level-api-resources.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import illustration from '@site/docs/authorization/assets/rbac-organization-leve
66
import AuthorizationRequestExample from '@site/docs/authorization/fragments/AuthorizationRequestExample';
77
import ClientCredentialsRequestExample from '@site/docs/authorization/fragments/ClientCredentialsRequestExample';
88
import TokenRequestExample from '@site/docs/authorization/fragments/TokenRequestExample';
9+
import HandleUserPermissionChange from '@site/docs/authorization/fragments/_handle-user-permission-change.mdx';
910
import TabItem from '@theme/TabItem';
1011
import Tabs from '@theme/Tabs';
1112

@@ -210,6 +211,8 @@ When your app receives an organization token, you should:
210211

211212
For step-by-step and language-specific guides, see [How to validate access tokens](/authorization/validate-access-tokens).
212213

214+
<HandleUserPermissionChange type="organization" />
215+
213216
## Best practices and security tips \{#best-practices-and-security-tips}
214217

215218
- **Always validate the organization context:** Don’t trust just the token; check the `organization_id` claim for every organization-scoped API call.

docs/authorization/organization-permissions.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import illustration from '@site/docs/authorization/assets/rbac-organization-perm
66
import AuthorizationRequestExample from '@site/docs/authorization/fragments/AuthorizationRequestExample';
77
import ClientCredentialsRequestExample from '@site/docs/authorization/fragments/ClientCredentialsRequestExample';
88
import TokenRequestExample from '@site/docs/authorization/fragments/TokenRequestExample';
9+
import HandleUserPermissionChange from '@site/docs/authorization/fragments/_handle-user-permission-change.mdx';
910
import TabItem from '@theme/TabItem';
1011
import Tabs from '@theme/Tabs';
1112

@@ -198,6 +199,8 @@ When your app receives an organization token, you should:
198199

199200
For step-by-step and language-specific guides, see [How to validate access tokens](/authorization/validate-access-tokens).
200201

202+
<HandleUserPermissionChange type="organization" />
203+
201204
## Best practices and security tips \{#best-practices-and-security-tips}
202205

203206
- **Never rely solely on UI enforcement:** Always validate permissions on the backend for critical actions.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
"glob@>=10.2.0 <10.5.0": "^10.5.0"
108108
},
109109
"onlyBuiltDependencies": [
110+
"@swc/core",
110111
"core-js",
111112
"core-js-pure",
112113
"sharp"

0 commit comments

Comments
 (0)