Join us from October 8-10 in New York City to learn the latest tips, trends, and news about GraphQL Federation and API platform engineering.Join us for GraphQL Summit 2024 in NYC
Start for Free

Authenticating Requests with the GraphOS Router

Use authorization and authentication strategies to secure your graph


Self-hosting the is limited to GraphOS Enterprise plans. Other plan types use managed cloud routing with GraphOS. Check out the pricing page to learn more.


If you're an enterprise customer looking for more material on this topic, try the Enterprise best practices: Router extensibility course on .

Not an enterprise customer? Learn about GraphOS for Enterprise.

When using the as the entry point to your federated , you have a few options for authenticating incoming client requests:

In fact, we recommend you combine all three strategies to create a more robust authentication system!

Use authorization directives

In addition to the approaches outlined below, you can use authorization directives to enforce authorization at the router layer. This allows you to authorize requests prior to them hitting your saving on bandwidth and processing time.

This is an Enterprise feature of the GraphOS Router. It requires an organization with a GraphOS Enterprise plan.

SubgraphRouterClientSubgraphRouterClientValidate requestalt[Request is invalid][Request is valid]Request with tokenRespond 401 UnauthorizedRequest Data

Once the request's claims are made available via the JWT validation or a coprocessor, they can be used to match against the required type and scopes to enforce authorization policies.

# Request's authorization claims must contain `read:users`
type Query {
users: [User!]! @requiresScopes(scopes: [["read:users"]])
# Request must be authenticated
type Mutation {
updateUser(input: UpdateUserInput!): User! @authenticated


  • Validating authorization before processing requests enables the early termination of unauthorized requests reducing the load on your services
  • Declarative approach that can be adopted and maintained by each while enforced centrally


  • Schema updates will need to be made to each subgraph to opt into this authorization model

Authenticate in subgraphs

The simplest authentication strategy is to delegate authentication to your individual subgraph services.

SubgraphRouterClientSubgraphRouterClientAuthenticate request with tokenRequest with tokenRequest with token

To pass Authentication headers from client requests to your subgraphs, add the following to your router's YAML configuration file:

- propagate:
named: authorization


  • Requires minimal changes to your router configuration.
  • Can take advantage of existing authentication code in subgraphs, which is often tied to authorization logic for .


  • Each subgraph that contributes to resolving a request needs to authenticate that request.
  • If subgraphs are written in different languages, maintaining consistent authentication code for each is complex.

Use the JWT Authentication plugin

As of router v1.13, you can use the JWT Authentication plugin to validate JWT-based authentication tokens in your supergraph.

This feature is only available with a GraphOS Dedicated or Enterprise plan.
To compare GraphOS feature support across all plan types, see the pricing page.

SubgraphJWKS EndpointRouterClientSubgraphJWKS EndpointRouterClientValidate JWTExtract claims in RhaiCheck claims on headersRequest with JWTFetch key setPublic keysRequest with extracted claims in headers

- url:


  • The router prevents unauthenticated requests from reaching your subgraphs.
  • The router can extract claims from the JWT and pass them to your subgraphs as headers, reducing logic needed in your subgraphs.


  • It supports only JWT-based authentication with keys from a JWKS endpoint.

Use a coprocessor

If you have a custom authentication strategy, you can use a coprocessor to implement it.

This feature is only available with a GraphOS Dedicated or Enterprise plan.
To compare GraphOS feature support across all plan types, see the pricing page.

SubgraphCoprocessorRouterClientSubgraphCoprocessorRouterClientValidate requestCan also add new headersalt[Request is invalid][Request is valid]Check claims on headersRequest with tokenRequest with headers and contextRespond { control: { break: 401 } }Respond { control: "continue" }Request with new headers

headers: true

This example coprocessor is written in Node.js and uses Express:

const app = express();
app.use(bodyParser.json());'/', async (req, res) => {
const {headers} = req.body;
const token = headers.authorization;
const isValid = await validateToken(token);
if (!isValid) {
control: {break: 401}
} else {
control: 'continue',
headers: {'x-claims': extractClaims(token)}


  • You can implement any authentication strategy in any language or framework, as long as the coprocessor provides an HTTP endpoint.
  • You can use the coprocessor to add headers to requests, which can be used by your subgraphs for additional authorization.


  • The initial lift of implementing a coprocessor is non-trivial, but once it's in place you can leverage it for any number of router customizations.

Combining authentication strategies

You can combine the strategies to handle a number of authentication requirements and practice "defense-in-depth":

  1. Use the JWT Authentication plugin to validate JWT-based authentication tokens.
  2. Use auth to enforce authentication and authorization and at the supergraph layer
  3. Use a coprocessor to identify traffic using a legacy authentication strategy and convert legacy session tokens to JWTs.
  4. Forward JWTs to subgraphs for additional authorization.
Rate articleRateEdit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc., d/b/a Apollo GraphQL.

Privacy Policy