Authenticating requests with the Apollo Router
Self-hosting the Apollo Router is limited to Apollo Enterprise plans. Other plan types use managed cloud routing with GraphOS.
When using the Apollo Router as the entry point to your federated supergraph, you have a few options for authenticating incoming client requests:
- Delegate authentication to your subgraphs.
- Use the JWT Authentication plugin to your supergraph.
- Use a coprocessor.
In fact, we recommend you combine all three strategies to create a more robust authentication system!
Authenticate in subgraphs
The simplest authentication strategy is to delegate authentication to your individual subgraph services.
To pass Authentication
headers from client requests to your subgraphs, add the following to your router's YAML configuration file:
headers:all:request:- propagate:named: authorization
Pros
- Requires minimal changes to your router configuration.
- Can take advantage of existing authentication code in subgraphs, which is often tied to authorization logic for data sources.
Cons
- 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 Apollo Router v1.13, you can use the JWT Authentication plugin to validate JWT-based authentication tokens in your supergraph.
⚠️ This is an Enterprise feature of the Apollo Router. It requires an organization with a GraphOS Enterprise plan.
authentication:jwt:jwks:- url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json
Pros:
- 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.
Cons:
- 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 is an Enterprise feature of the Apollo Router. It requires an organization with a GraphOS Enterprise plan.
coprocessor:url: http://127.0.0.1:8081router:request:headers: true
This example coprocessor is written in Node.js and uses Express:
const app = express();app.use(bodyParser.json());app.post('/', async (req, res) => {const {headers} = req.body;const token = headers.authorization;const isValid = await validateToken(token);if (!isValid) {res.json({...req.body,control: {break: 401}});} else {res.json({...req.body,control: 'continue',headers: {'x-claims': extractClaims(token)}});}});
Pros:
- 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.
Cons:
- 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":
- Use a coprocessor to identify traffic using a legacy authentication strategy and convert legacy session tokens to JWTs.
- Use the JWT Authentication plugin to validate JWT-based authentication tokens.
- Forward JWTs to subgraphs for additional authorization.