Files
Edu/infra/apollo-router/router.yaml
SpecialX caa90eba85 feat(infra): enable apollo-router APQ + manifest + depth/cost limits
Task 14 of portal-shell data abstraction plan (M3 security).

router.yaml:
- persisted_queries: enabled + require_manifest (env-controlled)
- limits: max_depth=10, max_cost=1000, max_batch_size=5
- introspection: env-controlled (prod=false, dev=true)

docker-compose.yml:
- Mount portal-shell/public/pq-manifest.json as read-only volume
- Add APOLLO_REQUIRE_PQ_MANIFEST + APOLLO_ROUTER_INTROSPECTION env vars
- Dev defaults preserve current behavior (manifest optional)

entrypoint.sh:
- Pre-start check: if require_manifest=true, fail fast when manifest missing
- Dev mode: warn but continue when manifest absent

Production enables strict mode via env:
  APOLLO_REQUIRE_PQ_MANIFEST=true
  APOLLO_ROUTER_INTROSPECTION=false
2026-07-17 13:32:46 +08:00

104 lines
3.1 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Apollo Router 配置v2.1 M2 + M3 安全加固)
#
# Router 作为唯一的外部 GraphQL 入口,替代 3 个 BFF 的手动聚合。
# 前端 → RouterGraphQL→ 各子图(/graphql
# 内部调用(后端 → 后端)仍走 gRPCADR-037
#
# 端口3000GraphQL/ 8088健康检查
# 镜像ghcr.io/apollographql/router:v1.45.0
#
# v2.1 M3 安全加固:
# - APQ + manifest 校验(生产拒绝未知 hash
# - 深度/复杂度限制
# - 生产关闭 introspection通过环境变量控制
# - 生产仅允许 POSTcsrf.enabled 阻止 GET 查询)
supergraph:
listen: 0.0.0.0:3000
path: /graphql
# 生产关闭 introspectionAPOLLO_ROUTER_INTROSPECTION=false
# 开发默认 true 便于调试
introspection: ${env.APOLLO_ROUTER_INTROSPECTION::true}
# 持久化查询v2.1 M3 安全加固)
# 关联portal-shell spec §4.3
# - enabled: 启用 APQ接受 hash-only 请求)
# - require_manifest: 生产设为 true仅接受 manifest 内的 hash
# - manifest_path: manifest 文件路径(由 portal-shell 构建产物挂载)
persisted_queries:
enabled: true
require_manifest: ${env.APOLLO_REQUIRE_PQ_MANIFEST::false}
manifest_path: /etc/apollo-router/pq-manifest.json
# 查询限制v2.1 M3 安全加固)
# 关联portal-shell spec §5.1
# - max_depth: 最大嵌套深度 10防止递归攻击
# - max_cost: 最大查询复杂度 1000防止放大攻击
# - max_batch_size: 批量查询上限 5防止 batch 攻击)
limits:
max_depth: 10
max_cost: 1000
max_batch_size: 5
# Sandbox 模式支持开发和调试v1.45 中 sandbox 已合并到 homepage
homepage:
enabled: true
# CORS允许前端 portal 访问
cors:
origins:
- "http://localhost:4000"
- "http://localhost:4001"
- "http://localhost:4002"
- "http://localhost:4003"
- "http://localhost:4010"
- "http://teacher-portal:4000"
- "http://student-portal:4001"
- "http://parent-portal:4002"
- "http://admin-portal:4003"
- "http://portal-shell:4010"
methods:
- GET
- POST
- OPTIONS
allow_credentials: true
allow_headers:
- Authorization
- Content-Type
- X-Request-Id
- X-Expected-Version
- If-Match
# 向所有子图注入 Router-Authorization HeaderADR-036
# 子图的 RouterAuthGuard 校验此 Header拒绝非 Router 的直接 GraphQL 请求
# 同时透传用户身份头x-user-id / x-user-role与 Authorization 到子图,
# 供 iam/core-edu/msg 等子图做用户级鉴权M8portal-shell 查询走 Router
headers:
all:
request:
- insert:
name: "router-authorization"
value: "dev-router-secret"
- propagate:
named: "Authorization"
- propagate:
named: "x-user-id"
- propagate:
named: "x-user-role"
- propagate:
named: "X-Request-Id"
# 健康检查
health_check:
listen: 0.0.0.0:8088
# 日志v1.45 使用 telemetry.exporters.logging
telemetry:
exporters:
logging:
stdout:
format: json
instrumentation:
spans:
mode: spec_compliant