All skills
apollographql avatar

/apollo-router

@f13ff34 official
by Apollo GraphQLapollographql/skills115 stars
13

Version-aware guide for configuring and running Apollo Router for federated GraphQL supergraphs. Generates correct YAML for both Router v1.x and v2.x. Use this skill when: (1) setting up Apollo Router to run a supergraph, (2) configuring routing, headers, or CORS, (3) implementing custom plugins (Rhai scripts or coprocessors), (4) configuring telemetry (tracing, metrics, logging), (5) troubleshooting Router performance or connectivity issues, (6) securing the graph with JWT, declarative field-level authorization directives, or persisted-query safelisting, (7) managing router.yaml as version-controlled config with CI/CD validation.

Use this Skill: https://skilld.dev/gh/apollographql/skills/apollo-router

This session only. Nothing lands on disk.

validationchecklist.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Post-Generation Validation Checklist

Run through this checklist after generating a router.yaml to catch common mistakes.

Security

  • Introspection disabled (production): supergraph.introspection: false
  • Sandbox disabled (production): sandbox.enabled: false
  • Homepage disabled (production): homepage.enabled: false
  • Subgraph errors hidden (production): include_subgraph_errors.all: false
  • No wildcard CORS (production): explicit origins only (no "*" and no allow_any_origin: true)
  • Authentication required (if applicable): authorization.require_authentication: true
  • Declarative authorization not silently disabled (if using @authenticated/@requiresScopes/@policy): authorization.directives.enabled is absent or true, router is GraphOS-connected, and a claims source (JWT auth or coprocessor) is configured
  • @policy evaluator wired (if @policy used): a Rhai script or coprocessor evaluates apollo::authorization::required_policies at the Supergraph stage
  • Safelisting vs APQ not confused: if the goal is an operation allowlist, persisted_queries.safelist.enabled: true is set (NOT just apq)
  • APQ disabled when safelisting (if persisted_queries.safelist.enabled: true): apq.enabled: false (mutually exclusive)
  • Persisted queries use GA key: persisted_queries (not preview_persisted_queries)

Version Correctness

  • CORS schema matches version:
    • v1: flat cors.origins: [...]
    • v2: cors.policies: [{ origins: [...] }]
  • JWT issuer field matches version:
    • v1: issuer: <string> (singular)
    • v2: issuers: [<string>] (plural array)
  • Max age format matches version:
    • v1: duration string (max_age: 24h)
    • v2: duration string (max_age: 24h)
  • Limits key is correct: Use limits (v1.17+ and v2), not preview_operation_limits
  • Connectors key is correct (if applicable): early v2 preview = preview_connectors, current v2 GA = connectors

Operational

  • Health check enabled: health_check.enabled: true with a listen address
  • Rate limiting on router:: traffic_shaping.router.global_rate_limit limits client requests; all: limits subgraph requests
  • All env vars documented: Every ${env.VAR} in the config has a corresponding entry in deployment docs
  • APOLLO_KEY not hardcoded: API key is via environment variable, never in config file or logs
  • Secrets use env var expansion: ${env.JWKS_URL}, ${env.JWT_ISSUER}, etc.
  • Config is version-controlled: router.yaml is committed to git (safe to share — no secrets) and changes go through review
  • CI validates config: router config validate router.yaml runs on every PR, pinned to the deployed Router version

Telemetry

  • Logging format is JSON (production): telemetry.exporters.logging.stdout.format: json
  • Tracing sampler is set: sampler: 0.1 (10%) is a reasonable default; tune for your traffic volume
  • Service name is set: common.service_name identifies this router instance

Response Caching (if enabled)

Security

  • User-specific fields identified: Confirmed with the user which fields return per-user data
  • Private scope set: User-specific subgraph responses include Cache-Control: private (via @cacheControl(scope: PRIVATE) in Apollo Server, or by setting the header directly in other frameworks)
  • private_id configured: Every subgraph serving private-scoped data has private_id set
  • User identifier extracted: Rhai script or coprocessor populates the private_id context key from auth token
  • No unprotected user data: Verified that no user-specific response is cached without Cache-Control: private
  • Debug mode disabled (production): response_cache.debug is absent or false
  • Invalidation endpoint not publicly exposed (production): bind to 127.0.0.1, not 0.0.0.0
  • Invalidation shared key uses env var: ${env.INVALIDATION_SHARED_KEY}

Operational

  • Redis URL uses env var: ${env.CACHE_REDIS_URL}, not hardcoded
  • TTL is set: explicit ttl on subgraph.all or per-subgraph
  • Redis credentials use env vars: No hardcoded passwords or usernames

Recommended Final Step

# Validate config syntax against the Router's schema
router config validate router.yaml

If migrating from v1 to v2, use the built-in upgrade tool:

router config upgrade router.yaml

Source: SKILL.md on GitHub

2 warnings16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a configuration generator and guide for Apollo Router. It implements robust security best practices by default, including environment variable interpolation for sensitive data, disabling developmental features (introspection/sandbox) in production, and providing a validation checklist. No malicious patterns, data exfiltration, or unauthorized command execution risks were found.

  • Socket16d

    1 alert: gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    26/26 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at f13ff34. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 4 months ago
What it can do
Runs commands
metadata
{
  "author": "apollographql",
  "version": "2.5.0"
}
All 1 allowed tools
Bash(router:*) Bash(./router:*) Bash(rover:*) Bash(curl:*) Bash(docker:*) Read Write Edit Glob Grep
Other metadata
compatibility
Linux/macOS/Windows. Requires a composed supergraph schema from Rover or GraphOS.
  • apollo-router
  • graphql
  • federation
  • routing
  • yaml
  • telemetry
  • authentication
  • cors

README badge

README badge for apollographql/skills/apollo-router

Generates version-aware Apollo Router configuration (v1.x or v2.x) for federated GraphQL supergraphs, handling routing, authentication, CORS, telemetry, and connectors. Use this skill to set up Router with JWT auth, traffic shaping, operation limits, or to troubleshoot connectivity and performance issues.

Generated from the current SKILL.md.

Does this skill support both Router v1 and v2?
Yes. The skill generates version-correct YAML for both v1.x and v2.x, which have incompatible config schemas. You must select your target version before generating any config.
Can I use this skill to configure Connectors?
Yes, but only for Router v2. Connectors (REST API integration) are a v2-only feature available in GA. The skill will not offer Connectors as an option if you select v1.
What do I need before I can run the generated config?
You need either a composed `supergraph.graphql` file from Rover or GraphOS access via `APOLLO_KEY` and `APOLLO_GRAPH_REF`. The skill assumes you have reachable subgraphs and will validate the config against the Router binary if available.
Does this skill help with response caching?
Yes, but only for Router v2.6.0 and later. The skill requires you to identify which subgraphs serve user-specific data and how you identify users before generating cache config, to prevent data leakage.
Will the skill validate my generated config?
Yes. After generating or editing config, the skill runs a checklist and attempts to validate against `router config validate` if the Router CLI is available. It will report pass/fail for each checklist item.

Generated from the current SKILL.md. These answers refresh after source changes.