-
Notifications
You must be signed in to change notification settings - Fork 122
docs(router): Add authorization documentation and specification #7302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a308eb2
fbb22ee
9344754
d0c9307
4952391
5c34e96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| --- | ||
| title: 'authorization' | ||
| --- | ||
|
|
||
| # authorization | ||
|
|
||
| The `authorization` configuration lets you control fine-grained access to your GraphQL schema using | ||
| directives like `@authenticated` and `@requiresScopes`. This allows you to restrict which fields | ||
| authenticated users can access based on their authentication status or specific scopes. | ||
|
|
||
| For practical examples and a guide to authorization concepts, see | ||
| **["Authorization"](../security/authorization)** in the documentation. | ||
|
|
||
| ## Directives | ||
|
|
||
| Access control is defined within the supergraph schema using the following directives: | ||
|
|
||
| - `@authenticated` - restricts access to authenticated users only | ||
| - `@requiresScopes(scopes: [[String]])` - restricts access based on specific scopes | ||
|
|
||
| ## Configuration Options | ||
|
|
||
| ### `enabled` | ||
|
|
||
| - **Type:** `boolean` | ||
| - **Default:** `true` | ||
|
|
||
| Whether to enable authorization directives processing. Set to `false` to disable authorization | ||
| checks entirely. | ||
|
|
||
| ### `unauthorized.mode` | ||
|
|
||
| - **Type:** `string` | ||
| - **Allowed values:** `"filter"` or `"reject"` | ||
| - **Default:** `"filter"` | ||
|
|
||
| Controls how the router handles unauthorized field access: | ||
|
|
||
| - `"filter"`: Remove unauthorized fields and continue processing (returns errors for removed fields) | ||
| - `"reject"`: Reject the entire request if any unauthorized fields are accessed | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Filter Mode (Default) | ||
|
|
||
| With `filter` mode, unauthorized fields are silently removed from the operation, but the query | ||
| continues to execute and return the data the user can access: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why might one choose reject over filter? And should we mention how nullability impacts this? A lot of developers who are new to graphql don't realize how error bubbling works.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A separate section about nullability yes, good idea, but imo explaining when to use each mode is kind of obvious to people (they know their behaviour and there's nothing more to add really) |
||
|
|
||
| ```yaml filename="router.config.yaml" | ||
| authorization: | ||
| directives: | ||
| enabled: true | ||
| unauthorized: | ||
| mode: filter | ||
| ``` | ||
|
|
||
| **Request:** | ||
|
|
||
| ```graphql | ||
| query { | ||
| publicData | ||
| me { | ||
| name | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| If the user is not authenticated, the response might look like: | ||
|
|
||
| ```json | ||
| { | ||
| "data": { | ||
| "publicData": "available", | ||
| "me": null | ||
| }, | ||
| "errors": [ | ||
| { | ||
| "message": "Unauthorized field or type", | ||
| "extensions": { | ||
| "code": "UNAUTHORIZED_FIELD_OR_TYPE", | ||
| "affectedPath": "me" | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| ### Reject Mode | ||
|
|
||
| With `reject` mode, if any field is unauthorized, the entire request is rejected: | ||
|
|
||
| ```yaml filename="router.config.yaml" | ||
| authorization: | ||
| directives: | ||
| enabled: true | ||
| unauthorized: | ||
| mode: reject | ||
| ``` | ||
|
|
||
| **Request (same as above):** | ||
|
|
||
| ```graphql | ||
| query { | ||
| publicData | ||
| me { | ||
| name | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Response:** | ||
|
|
||
| ```json | ||
| { | ||
| "data": null, | ||
| "errors": [ | ||
| { | ||
| "message": "Unauthorized field or type", | ||
| "extensions": { | ||
| "code": "UNAUTHORIZED_FIELD_OR_TYPE" | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that authorization is covered both in the configuration and security section, but this page is technically "authorization in the documentation" also.
I think it would be good to make a more clear delineation between the two documents. E.g.
security/authorizationcould talk about more broadly about authorization and high-level motives behind our approach, andconfiguration/authorizationcan provide the details about configuration options in the router and cover the specific directive definitions.This is true for most of the content in
Securitysubpages. We could move important details to their related configuration page, and makeSecuritya more high-level page that acts as an introduction to these features as concepts rather than provide too much detail up front.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to avoid writing high-level content and link people to different pages. The idea here is to give people a comprehensive guide on authorization and only branch out to other pages when it involves a bigger/standalone topic (like JWT - as it's not only about authorization, but authentication too).
The only thing that is configuration-specific is filter/reject mode. I forgot to remove the directives from this page.
The configuration pages will be generated from code once Dotan is back and I'm fine with duplicating content a bit.