Appearance
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-001slice 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.mdgo-platform/docs/architecture/api-contract-strategy.mdgo-platform/docs/agents/service-agent-execution-queue.jsongo-platform/docs/agents/service-agent-closeout-ledger.jsongo-platform/docs/agents/service-tasks/api-gateway.mdgo-platform/docs/agents/agent-handoff-format.mdgo-platform/docs/qa/service-agent-goal-completion-audit.mdgo-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.mdgo-platform/docs/agents/service-agent-closeout-ledger.jsongo-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_URLfor IAM RS256 JWKS verification while preservingAUTH_JWT_SECRETHS256 token verification for local route rehearsals. - Existing audited route auth forwards
X-User-Id,X-User-Role,X-User-Full-Name, optionalX-User-Email, andX-Organization-Idonly 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.jsonremains default and keeps/api/auth,/api/admin,/api/organizations,/api/exams,/api/attempts, and/apifallback onlegacy_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-002BFF owner-service read adapter or the gatedSVC-003/SVC-004IAM/Profile cutover hardening only after the required populated-target proof bundle is reviewed.