Skip to content

Commit 6a5666b

Browse files
committed
Add authorization documentation and specification
1 parent 8e01207 commit 6a5666b

File tree

4 files changed

+912
-11
lines changed

4 files changed

+912
-11
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
---
2+
title: 'authorization'
3+
---
4+
5+
# authorization
6+
7+
The `authorization` configuration lets you control fine-grained access to your GraphQL schema using
8+
directives. This allows you to restrict which fields authenticated users can access based on their
9+
authentication status or specific scopes.
10+
11+
## How Authorization Works
12+
13+
The router supports two modes for handling unauthorized field access:
14+
15+
- **`filter` (default mode):** This mode silently removes any fields from the incoming GraphQL
16+
operation that the user is not authorized to access. For each field removed, a corresponding
17+
authorization error is added to the `errors` list in the GraphQL response, while the rest of
18+
the accessible data is returned as requested.
19+
- **`reject` mode:** In this mode, the router will reject any GraphQL operation that attempts to
20+
access one or more unauthorized fields. The entire request is denied, and a descriptive error is
21+
returned.
22+
23+
## Directives
24+
25+
Access control is defined within the supergraph schema using the following directives:
26+
27+
### `@authenticated`
28+
29+
Restricts access to a field to only authenticated users. Any request without valid authentication
30+
(such as requests without a JWT token) will be prevented from accessing the field.
31+
32+
**Usage:**
33+
34+
```graphql
35+
type Query {
36+
me: User @authenticated
37+
publicData: String
38+
}
39+
```
40+
41+
### `@requiresScopes(scopes: [[String]])`
42+
43+
Provides more granular control by requiring the user to possess specific scopes. The directive
44+
supports:
45+
46+
- **`AND` logic** for scopes within a nested list (e.g., `[["read:users", "write:users"]]`) - the
47+
user must have all scopes in the list
48+
- **`OR` logic** for scopes across nested lists (e.g., `[["read:users"], ["admin:users"]]`) - the
49+
user must have scopes from at least one of the nested lists
50+
51+
**Usage:**
52+
53+
```graphql
54+
type Query {
55+
# User must have both scopes
56+
users: [User] @requiresScopes(scopes: [["read:users", "write:users"]])
57+
58+
# User must have either scope
59+
admin: AdminPanel @requiresScopes(scopes: [["admin:users"], ["admin:system"]])
60+
61+
# User must have read:users AND (admin:users OR admin:system)
62+
reports: [Report] @requiresScopes(scopes: [["read:users", "admin:users"], ["read:users", "admin:system"]])
63+
}
64+
```
65+
66+
## Configuration Options
67+
68+
### `enabled`
69+
70+
- **Type:** `boolean`
71+
- **Default:** `true`
72+
73+
Whether to enable authorization directives processing. Set to `false` to disable authorization checks entirely.
74+
75+
### `unauthorized.mode`
76+
77+
- **Type:** `string`
78+
- **Allowed values:** `"filter"` or `"reject"`
79+
- **Default:** `"filter"`
80+
81+
Controls how the router handles unauthorized field access:
82+
83+
- `"filter"`: Remove unauthorized fields and continue processing (returns errors for removed fields)
84+
- `"reject"`: Reject the entire request if any unauthorized fields are accessed
85+
86+
## Examples
87+
88+
### Filter Mode (Default)
89+
90+
With `filter` mode, unauthorized fields are silently removed from the operation, but the query
91+
continues to execute and return the data the user can access:
92+
93+
```yaml filename="router.config.yaml"
94+
authorization:
95+
directives:
96+
enabled: true
97+
unauthorized:
98+
mode: filter
99+
```
100+
101+
**Request:**
102+
103+
```graphql
104+
query {
105+
publicData
106+
me {
107+
name
108+
email
109+
}
110+
}
111+
```
112+
113+
If the user is not authenticated, the response might look like:
114+
115+
```json
116+
{
117+
"data": {
118+
"publicData": "available",
119+
"me": null
120+
},
121+
"errors": [
122+
{
123+
"message": "Unauthorized field or type",
124+
"extensions": {
125+
"code": "UNAUTHORIZED_FIELD_OR_TYPE",
126+
"affectedPath": "me"
127+
}
128+
}
129+
]
130+
}
131+
```
132+
133+
### Reject Mode
134+
135+
With `reject` mode, if any field is unauthorized, the entire request is rejected:
136+
137+
```yaml filename="router.config.yaml"
138+
authorization:
139+
directives:
140+
enabled: true
141+
unauthorized:
142+
mode: reject
143+
```
144+
145+
**Request (same as above):**
146+
147+
```graphql
148+
query {
149+
publicData
150+
me {
151+
name
152+
email
153+
}
154+
}
155+
```
156+
157+
**Response:**
158+
159+
```json
160+
{
161+
"data": null,
162+
"errors": [
163+
{
164+
"message": "Unauthorized field or type",
165+
"extensions": {
166+
"code": "UNAUTHORIZED_FIELD_OR_TYPE"
167+
}
168+
}
169+
]
170+
}
171+
```

packages/web/docs/src/content/router/configuration/index.mdx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,19 @@ Some configuration variables can be overridden at runtime using
1313
This page covers all the main configuration options available. Each option links to a detailed page
1414
that explains how to use that feature.
1515

16-
- [`cors`](./configuration/cors): Control cross-origin requests to your API.
17-
- [`csrf`](./configuration/csrf): Protect against cross-site request forgery attacks.
18-
- [`headers`](./configuration/headers): Modify HTTP headers between clients and subgraphs.
19-
- [`http`](./configuration/http): Set the host and port for your router.
20-
- [`jwt`](./configuration/jwt): Add JWT-based authentication to secure your endpoint.
21-
- [`log`](./configuration/log): Control what the router logs and how it formats log messages.
22-
- [`override_subgraph_urls`](./configuration/override_subgraph_urls): Route requests to different
16+
- [`authorization`](./authorization): Define field-level access control using directives.
17+
- [`cors`](./cors): Control cross-origin requests to your API.
18+
- [`csrf`](./csrf): Protect against cross-site request forgery attacks.
19+
- [`headers`](./headers): Modify HTTP headers between clients and subgraphs.
20+
- [`http`](./http): Set the host and port for your router.
21+
- [`jwt`](./jwt): Add JWT-based authentication to secure your endpoint.
22+
- [`log`](./log): Control what the router logs and how it formats log messages.
23+
- [`override_subgraph_urls`](./override_subgraph_urls): Route requests to different
2324
subgraph URLs dynamically.
24-
- [`override_labels`](./configuration/override_labels): Dynamically activate or deactivate
25+
- [`override_labels`](./override_labels): Dynamically activate or deactivate
2526
progressive override labels.
26-
- [`query_planner`](./configuration/query_planner): Add safety limits and debugging for query
27+
- [`query_planner`](./query_planner): Add safety limits and debugging for query
2728
planning.
28-
- [`supergraph`](./configuration/supergraph): Tell the router where to find your supergraph schema.
29-
- [`traffic_shaping`](./configuration/traffic_shaping): Manage connection pooling and request
29+
- [`supergraph`](./supergraph): Tell the router where to find your supergraph schema.
30+
- [`traffic_shaping`](./traffic_shaping): Manage connection pooling and request
3031
handling to subgraphs.

packages/web/docs/src/content/router/security/_meta.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export default {
2+
authorization: 'Authorization',
23
cors: 'Configuring CORS',
34
csrf: 'CSRF Prevention',
45
'jwt-authentication': 'JWT Authentication',

0 commit comments

Comments
 (0)