Skills apollo-router
git clone https://github.com/apollographql/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/apollographql/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/apollo-router" ~/.claude/skills/apollographql-skills-apollo-router && rm -rf "$T"
skills/apollo-router/SKILL.mdApollo Router Config Generator
Apollo Router is a high-performance graph router written in Rust for running Apollo Federation 2 supergraphs. It sits in front of your subgraphs and handles query planning, execution, and response composition.
This skill generates version-correct configuration. Router v1 and v2 have incompatible config schemas in several critical sections (CORS, JWT auth, connectors). Always determine the target version before generating any config.
Step 1: Version Selection
Ask the user before generating any config:
Which Apollo Router version are you targeting? [1] Router v2.x (recommended — current LTS, required for Connectors) [2] Router v1.x (legacy — end-of-support announced, security patches only) [3] Not sure — help me decide
If the user picks [3], display:
Quick guide: • Pick v2 if: you're starting fresh, using Apollo Connectors for REST APIs, or want backpressure-based overload protection. • Pick v1 if: you have an existing deployment and haven't migrated yet. Note: Apollo ended active support for v1.x. The v2.10 LTS (Dec 2025) is the current baseline. Migration is strongly recommended. Tip: If you have an existing router.yaml, you can auto-migrate it: router config upgrade router.yaml
Store the selection as
ROUTER_VERSION=v1|v2 to gate all subsequent template generation.
Step 2: Environment Selection
Ask: Production or Development?
- Production: security-hardened defaults (introspection off, sandbox off, homepage off, subgraph errors hidden, auth required, health check on)
- Development: open defaults (introspection on, sandbox on, errors exposed, text logging)
Load the appropriate base template from:
templates/{version}/production.yamltemplates/{version}/development.yaml
Step 3: Feature Selection
Ask which features to include:
- JWT Authentication
- CORS (almost always yes for browser clients)
- Operation Limits
- Traffic Shaping / Rate Limiting
- Telemetry (Prometheus, OTLP tracing, JSON logging)
- APQ (Automatic Persisted Queries)
- Connectors (REST API integration — Router v2 only; GA key is
, early v2 preview key wasconnectors
)preview_connectors - Subscriptions
- Header Propagation
Step 4: Gather Parameters
For each selected feature, collect required values.
- Use section templates from
fortemplates/{version}/sections/
,auth
,cors
,headers
,limits
, andtelemetry
.traffic-shaping - For Connectors in v2, use
as the source.templates/v2/sections/connectors.yaml - For APQ and subscriptions, copy the snippet from the selected base template (
ortemplates/{version}/production.yaml
) or from references.templates/{version}/development.yaml - Only offer Connectors when
.ROUTER_VERSION=v2
CORS
- List of allowed origins (never use
for production)"*"
JWT Authentication
- JWKS URL
- Issuer(s) — note: v1 uses singular
, v2 uses pluralissuer
arrayissuers
Connectors (v2 only)
- Subgraph name and source name (used as
)connectors.sources.<subgraph>.<source> - Optional
values for connector runtime configuration$config - If migrating old v2 preview config, rename
topreview_connectorsconnectors
Operation Limits
Present the tuning guidance:
Operation depth limit controls how deeply nested a query can be. Router default: 100 (permissive — allows very deep queries) Recommended starting point: 50 Lower values (15–25) are more secure but will reject legitimate queries in schemas with deep entity relationships or nested fragments. Higher values (75–100) are safer for compatibility but offer less protection against depth-based abuse. Tip: Run your router in warn_only mode first to see what depths your real traffic actually uses, then tighten: limits: warn_only: true What max_depth would you like? [default: 50]
The same principle applies to
max_height, max_aliases, and max_root_fields.
Telemetry
- OTEL collector endpoint (default:
)http://otel-collector:4317 - Prometheus listen port (default:
)9090 - Trace sampling rate (default:
= 10%)0.1
Traffic Shaping
- Client-facing rate limit capacity (default: 1000 req/s)
- Router timeout (default: 60s)
- Subgraph timeout (default: 30s)
Step 5: Generate Config
- Load the correct version template from
templates/{version}/ - Assemble section templates for supported sectioned features, then merge base-template snippets for APQ/subscriptions as needed
- Inject user-provided parameters
- Add a comment block at the top stating the target version
Step 6: Validate
Run the post-generation checklist:
- All env vars referenced in config are documented
- CORS origins don't include wildcards (production)
- Rate limiting is on
(client-facing), not onlyrouter:
(subgraph)all: - JWT uses
(v2) notissuers
(v1), or vice versaissuer - If production: introspection=false, sandbox=false, subgraph_errors=false
- Health check is enabled
- Homepage is disabled (production)
- Run:
if Router binary is availablerouter config validate <file>
Required Validation Gate (always run)
After generating or editing any
router.yaml, you MUST:
- Run
and report pass/fail for each checklist item.validation/checklist.md - Run
if Router CLI is available.router config validate <path-to-router.yaml> - If Router CLI is unavailable, state that explicitly and still complete the checklist.
- Do not present the configuration as final until validation is completed.
Step 7: Conditional Next Steps Handoff
After answering any Apollo Router request (config generation, edits, validation, or general Router guidance), decide whether the user already has runnable prerequisites:
- GraphOS-managed path:
+APOLLO_KEY
, orAPOLLO_GRAPH_REF - Local path: a composed
plus reachable subgraphssupergraph.graphql
If prerequisites are already present, do not add extra handoff text.
If prerequisites are missing or unknown, end with a concise Next steps handoff (1-3 lines max) that is skill-first and command-free:
- Suggest the
skill to compose or fetch the supergraph schema.rover - Suggest continuing with
once the supergraph is ready to validate and run with the generated config.apollo-router - If subgraphs are missing, suggest
,apollo-server
, andgraphql-schema
skills to scaffold and test.graphql-operations
Do not include raw shell commands in this handoff unless the user explicitly asks for commands.
Quick Start (skill-first)
- Use this
skill to generate or refineapollo-router
for your environment.router.yaml - Choose a runtime path:
- GraphOS-managed path: provide
andAPOLLO_KEY
(no local supergraph composition required).APOLLO_GRAPH_REF - Local supergraph path: use
+graphql-schema
to define/run subgraphs, then useapollo-server
for smoke tests, then use thegraphql-operations
skill to compose or fetchrover
.supergraph.graphql
- GraphOS-managed path: provide
- Use this
skill to validate readiness (apollo-router
) and walk through runtime startup inputs.validation/checklist.md
Default endpoint remains
http://localhost:4000 when using standard Router listen defaults.
If the user asks for executable shell commands, provide them on request. Otherwise keep Quick Start guidance skill-oriented.
Running Modes
| Mode | Command | Use Case |
|---|---|---|
| Local schema | | Development, CI/CD |
| GraphOS managed | | Production with auto-updates |
| Development | | Local development |
| Hot reload | | Schema changes without restart |
Environment Variables
| Variable | Description |
|---|---|
| API key for GraphOS |
| Graph reference () |
| Path to |
| Path to supergraph schema |
| Log level (off, error, warn, info, debug, trace) |
| Override listen address |
Reference Files
- Configuration — YAML configuration reference
- Headers — Header propagation and manipulation
- Plugins — Rhai scripts and coprocessors
- Telemetry — Tracing, metrics, and logging
- Connectors — Router v2 connectors configuration
- Troubleshooting — Common issues and solutions
- Divergence Map — v1 ↔ v2 config differences
- Validation Checklist — Post-generation checks
CLI Reference
router [OPTIONS] Options: -s, --supergraph <PATH> Path to supergraph schema file -c, --config <PATH> Path to router.yaml configuration --dev Enable development mode --hot-reload Watch for schema changes --log <LEVEL> Log level (default: info) --listen <ADDRESS> Override listen address -V, --version Print version -h, --help Print help
Ground Rules
- ALWAYS determine the target Router version (v1 or v2) before generating config
- DEFAULT to v2 for new projects
- ALWAYS include a comment block at top of generated config stating the target version
- ALWAYS use
mode for local development (enables introspection and sandbox)--dev - ALWAYS disable introspection, sandbox, and homepage in production
- PREFER GraphOS managed mode for production (automatic updates, metrics)
- USE
for local development with file-based schemas--hot-reload - NEVER expose
in logs or version controlAPOLLO_KEY - USE environment variables (
) for all secrets and sensitive config${env.VAR} - PREFER YAML configuration over command-line arguments for complex setups
- TEST configuration changes locally before deploying to production
- WARN if user enables
or wildcard CORS in productionallow_any_origin - RECOMMEND
for v1 → v2 migration instead of regenerating from scratchrouter config upgrade router.yaml - MUST run
after every router config generation or editvalidation/checklist.md - MUST run
when Router CLI is availablerouter config validate <file> - MUST report when CLI validation could not run (for example, Router binary missing)
- MUST append a brief conditional handoff when runtime prerequisites are missing or unknown
- MUST make this handoff skill-first and avoid raw shell commands unless the user explicitly requests commands
- MUST keep Quick Start guidance skill-first and command-free unless the user explicitly requests commands
- MUST state that Rover is required only for the local supergraph path; GraphOS-managed runtime does not require local Rover composition
- USE
as the default starting point, not 15 (too aggressive) or 100 (too permissive)max_depth: 50 - RECOMMEND
for initial limits rollout to observe real traffic before enforcingwarn_only: true