Skip to content

Commit 7cebdb6

Browse files
PAPI-3137 - Added details on access scoping, scope identifiers, and error handling for insufficient access scopes. Updated instructions for creating private tokens to include required scopes.
1 parent 6095619 commit 7cebdb6

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

docs/start/authentication/graphql-storefront.mdx

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,14 +295,49 @@ Private tokens are designed for server-to-server integrations. They are always s
295295
- **Server-to-server only:** The API rejects private token-authenticated requests that originate from web browsers
296296
- **Always stateless:** No session or cookie validation required
297297
- **Required for server-to-server:** Private tokens are required for server-to-server integrations without customer impersonation. Storefront tokens cannot be used statelessly in server-to-server contexts.
298+
- **Access scoping:** Only private tokens support access scopes (other token types do not). See [Private token access scopes](#private-token-access-scopes) below.
298299

299300
<Callout type="info">
300301
Private tokens are the recommended choice for new server-to-server integrations that don't require customer impersonation. They provide better performance and are designed specifically for stateless server-to-server use cases.
301302
</Callout>
302303

304+
### Private token access scopes
305+
306+
Only **private tokens** use access scopes; storefront and customer access tokens do not. Scopes restrict which GraphQL fields the token can access. The token must include **all** scopes required by every field in the selection (including nested fields).
307+
308+
**Scopes are independent:** There is no hierarchy or inheritance. For example, `TOKEN_SCOPE_CUSTOMER` does not include or imply `TOKEN_SCOPE_UNAUTHENTICATED`—they cover different areas. You need more than one scope only when your query selects fields that require different scopes (e.g. `checkout { order { id } }` requires both Unauthenticated for `checkout` and Customer for `order`).
309+
310+
**Scope identifiers** (use these in the create request):
311+
312+
| Scope | Use |
313+
|-------|-----|
314+
| `TOKEN_SCOPE_UNAUTHENTICATED` | Store, channel, catalog, products, content, cart, checkout (except nested `order`), wishlist create/public, analytics, payment, newsletter. |
315+
| `TOKEN_SCOPE_CUSTOMER` | Customer identity, orders, login/logout, session sync, registration (`registerCustomer`), customer wishlists, cart assignment, order messages. |
316+
| `TOKEN_SCOPE_B2B` | Company operations (e.g. `registerCompany`). |
317+
318+
If you create a token with **no scopes** (or an empty `scopes` array), it will have access to almost nothing; most fields require at least `TOKEN_SCOPE_UNAUTHENTICATED`. Apply the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege)—request only the scopes you need.
319+
320+
When the token lacks a scope required by a field, the API returns a GraphQL response with `errors`. Affected fields may be `null` in `data`. The error includes `extensions.code: "INSUFFICIENT_ACCESS_SCOPE"` and `extensions.requiredScopes` (the scope identifiers required by that field):
321+
322+
```json filename="Example: insufficient access scope error" showLineNumbers copy
323+
{
324+
"data": null,
325+
"errors": [
326+
{
327+
"message": "The provided token does not include the scopes required to resolve this field.",
328+
"path": ["company"],
329+
"extensions": {
330+
"code": "INSUFFICIENT_ACCESS_SCOPE",
331+
"requiredScopes": ["TOKEN_SCOPE_B2B"]
332+
}
333+
}
334+
]
335+
}
336+
```
337+
303338
### Create a private token
304339

305-
Use the [Create a private token](/docs/rest-authentication/tokens#create-a-private-api-token) REST endpoint to create private tokens. Add the [storefront API tokens creation scope](/docs/start/authentication/api-accounts#token-creation-scopes) to the [store-level or app-level API account](/docs/start/authentication/api-accounts) you use to generate tokens.
340+
You **must** specify `scopes` when creating a private token. Use the [Create a private token](/docs/rest-authentication/tokens#create-a-private-api-token) REST endpoint to create private tokens. Add the [storefront API tokens creation scope](/docs/start/authentication/api-accounts#token-creation-scopes) to the [store-level or app-level API account](/docs/start/authentication/api-accounts) you use to generate tokens.
306341

307342
<Tabs items={['Request', 'Response']}>
308343
<Tab>
@@ -314,8 +349,13 @@ accept: application/json
314349
content-type: application/json
315350
316351
{
317-
"channel_ids": [1, 2, 3], // array of integers (must be valid channel IDs on the store)
318-
"expires_at": 1602288000 // when the token will expire, as an integer unix timestamp (in seconds)
352+
"expires_at": 1602288000, // when the token will expire, as an integer unix timestamp (in seconds)
353+
"channel_ids": [1, 2, 3], // array of integers (must be valid channel IDs on the store)
354+
"scopes": [ // access scope identifiers (required)
355+
"TOKEN_SCOPE_UNAUTHENTICATED",
356+
"TOKEN_SCOPE_CUSTOMER",
357+
"TOKEN_SCOPE_B2B"
358+
]
319359
}
320360
```
321361
</Tab>

0 commit comments

Comments
 (0)