Skip to content

Handoff: SVC-001-protected-route-jwks-rehearsal api-gateway protected route and JWKS fallback rehearsal

Scope

  • Service/area: api-gateway
  • Task pack: docs/agents/service-tasks/api-gateway.md
  • Goal: accept the bounded SVC-001 slice for protected gateway route authentication using IAM RS256 JWKS verification, HS256 local fallback compatibility, role/organization guard checks, and rollback-safe route-table evidence.
  • Non-goals: default route promotion, service DB work, IAM credential/session ownership, profile storage, frontend rewrites, or changes to legacy source under /Users/velikho/Desktop/WORKING/HOCTAPAZ/.

Docs Read

  • go-platform/docs/architecture/service-responsibility-matrix.md
  • go-platform/docs/architecture/api-contract-strategy.md
  • go-platform/docs/agents/service-agent-execution-queue.json
  • go-platform/docs/agents/service-agent-closeout-ledger.json
  • go-platform/docs/agents/service-tasks/api-gateway.md
  • go-platform/docs/agents/agent-handoff-format.md
  • go-platform/docs/qa/service-agent-goal-completion-audit.md
  • go-platform/docs/qa/service-agent-readiness-smoke.md

Legacy Evidence Read

  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/main.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/web/lib/api-config.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/web/lib/api.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/web/lib/client-api.ts
  • Legacy source was read-only evidence only; no legacy parity claim is made beyond the gateway contract and route boundary checked here.

Files Changed

  • go-platform/docs/agents/handoffs/SVC-001-protected-route-jwks-rehearsal.md
  • go-platform/docs/agents/service-agent-closeout-ledger.json
  • go-platform/docs/agents/service-agent-closeout-ledger.md

Behavior Implemented

  • No new runtime code was implemented in this handoff.
  • Existing audited gateway wiring reads IAM_JWKS_URL/GATEWAY_JWKS_URL for IAM RS256 JWKS verification while preserving AUTH_JWT_SECRET HS256 token verification for local route rehearsals.
  • Existing audited route auth forwards X-User-Id, X-User-Role, X-User-Full-Name, optional X-User-Email, and X-Organization-Id only after bearer verification, role check, and required organization check.
  • Existing audited route examples keep auth/profile/organization/attempt/BFF native candidates in non-default route tables while the default route table remains legacy-backed.

Tests And Verification

  • Command: GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/...
  • Result: passed.
  • Evidence: api-gateway command and internal gateway tests passed.
  • Command: GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/internal/gateway -run 'TestGatewayNativeRouteAuthAcceptsIAMRS256JWKS|TestGatewayNativeRouteAuthRejectsIAMRS256RoleMismatch|TestGatewayNativeRouteAuthRejectsUnknownJWKSKey|TestGatewayNativeRouteAuthKeepsHS256FallbackWhenJWKSConfigured|TestGatewayNativeRouteAuthRejectsInvalidRequests' -count=1 -v
  • Result: passed.
  • Evidence: focused protected-route tests covered IAM RS256 JWKS accept, RS256 role denial, unknown JWKS key denial, HS256 fallback without calling JWKS, missing token, role denial, and required organization denial.
  • Command: make test-auth-routes
  • Result: passed.
  • Evidence: default auth route table stayed legacy; auth native examples passed route coverage; live, browser, session-browser, and IAM/Profile rollback scripts passed self-test mode.
  • Command: make test-profile-routes
  • Result: passed.
  • Evidence: profile, teacher KYC, admin KYC route coverage and profile live/browser self-tests passed.
  • Command: make test-organization-routes test-attempt-routes test-bff-routes
  • Result: passed.
  • Evidence: organization, attempt, and BFF non-default route examples passed route coverage; BFF focused gateway tests passed.
  • Command: make test-frontend-boundary
  • Result: passed.
  • Evidence: frontend boundary guard confirmed frontend apps do not call service internals directly.

Route State

  • Legacy route: deploy/gateway/routes.json remains default and keeps /api/auth, /api/admin, /api/organizations, /api/exams, /api/attempts, and /api fallback on legacy_proxy.
  • Native route: deploy/gateway/routes.auth-native-example.json, routes.auth-native-localhost-example.json, profile, organization, attempt, and BFF example route tables remain non-default rehearsals.
  • Gateway state: protected route behavior is proven by focused gateway tests and route-table guards; IAM remains the JWT/JWKS/role/permission owner.
  • Rollback: keep using deploy/gateway/routes.json; do not promote protected native routes until route-specific live/browser proof, candidate diff/review, and rollback proof are attached for the exact route being promoted.

Data Notes

  • Tables touched: none.
  • Migration run: none.
  • Validation report: not applicable because no data was migrated.

Risks / Blockers

  • Direct live/browser commands for default promotion were not rerun in this handoff because no long-running gateway/web/IAM runtime was promoted or required for this bounded acceptance.
  • Existing live/browser artifacts remain evidence for prior auth/profile rehearsals, but default route promotion still requires fresh route-specific runtime/browser proof and rollback review at promotion time.
  • This handoff does not complete IAM/Profile populated-target cutover, BFF owner-service handoffs, or service-by-service route migration.

Next Step

  • Pick the next bounded service row, prefer SVC-002 BFF owner-service read adapter or the gated SVC-003/SVC-004 IAM/Profile cutover hardening only after the required populated-target proof bundle is reviewed.

Go-platform documentation is generated from repository Markdown.