diff --git a/.changesets/docs_geal_authorization_router_rhai.md b/.changesets/docs_geal_authorization_router_rhai.md new file mode 100644 index 0000000000..0e3596252b --- /dev/null +++ b/.changesets/docs_geal_authorization_router_rhai.md @@ -0,0 +1,5 @@ +### GraphOS authorization: add an example of scope manipulation with router service level rhai ([PR #3719](https://github.com/apollographql/router/pull/3719)) + +The router authorization directive `@requiresScopes` expects scopes to come from the `scope` claim in the OAuth2 access token format ( https://datatracker.ietf.org/doc/html/rfc6749#section-3.3 ). Some tokens may have scopes stored in a different way, like an array of strings, or even in different claims. This documents a way to extract the scopes and prepare them in the right format for consumption by `@requiresScopes`, ushing Rhai. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/3719 \ No newline at end of file diff --git a/docs/source/configuration/authorization.mdx b/docs/source/configuration/authorization.mdx index 1b6d1e47f8..1a21b54a1c 100644 --- a/docs/source/configuration/authorization.mdx +++ b/docs/source/configuration/authorization.mdx @@ -140,6 +140,39 @@ claims = context["apollo_authentication::JWT::claims"] claims["scope"] = "scope1 scope2 scope3" ``` + + +If the `apollo_authentication::JWT::claims` object holds scopes in another format, for example, an array of strings, or at a key other than `"scope"`, you can edit the claims with a [Rhai script](../customizations/rhai). + +The example below extracts an array of scopes from the `"roles"` claim and reformats them as a space-separated string. + +```Rhai +fn router_service(service) { + let request_callback = |request| { + let claims = request.context["apollo_authentication::JWT::claims"]; + let roles = claims["roles"]; + + let scope = ""; + if roles.len() > 1 { + scope = roles[0]; + } + + if roles.len() > 2 { + for role in roles[1..] { + scope += ' '; + scope += role; + } + } + + claims["scope"] = scope; + request.context["apollo_authentication::JWT::claims"] = claims; + }; + service.map_request(request_callback); +} +``` + + + #### Usage To use the `@requiresScopes` directive in a subgraph, you can [import it from the `@link` directive](/federation/federated-types/federated-directives/#importing-directives) like so: