# 3.1 — SQS: Gateway JWT validation against Authentik JWKS (GREEN) Phase: 3 — Authentication & Authorization Stage: GREEN ✅ Depends on: 8.2 (X-Service dispatcher), 8.10 (gate) ## Context SQS (kmsvc management-service) has placeholder env vars for JWT validation: - `KMSVC_AUTHENTIK_ISSUER_URL` - `KMSVC_AUTHENTIK_AUDIENCE` But **kmsvc code is unverified** — we don't know if it actually validates JWTs. **Phase 8.2 decision**: Gateway validates SQS JWTs at ingress (not pushing to kmsvc). ## Implementation (Done) - [x] `internal/auth/jwt.go`: JWT validator with JWKS caching - [x] Validates JWT signature against Authentik JWKS (RS256) - [x] Verifies claims: iss, aud, exp, nbf (60s skew) - [x] Checks `permissions` claim for sqs:read/sqs:write/wildcard - [x] Returns 403 with error details on failure - [x] JWKS cache: 15min TTL, auto-refresh on kid miss - [x] Wired into `internal/serviceadapter/router.go` for SQS - [x] Integration tests: - Reject without Authorization header (403) - Accept with valid JWT (pass to upstream) - Pass through for other services ## Dependencies - `github.com/MicahParks/keyfunc/v2`: JWKS fetching & caching - `github.com/golang-jwt/jwt/v5`: JWT parsing & validation ## Verification (Done) ```bash # No Authorization header -> 403 curl -w '%{http_code}' -H 'X-Service: sqs' -H 'X-Resource: send-message' \ https://api.riotpiao.com/ # expected: 403 ✅ # With valid JWT -> passes through (may 200/400/404 from upstream) export JWT=$(curl -s -X POST https://authentik.riotpiao.com/application/o/token/ \ -d "grant_type=client_credentials&client_id=&client_secret=&scope=openid" \ | jq -r '.access_token') curl -w '%{http_code}' -H "Authorization: Bearer $JWT" \ -H 'X-Service: sqs' -H 'X-Resource: send-message' \ https://api.riotpiao.com/ # expected: not 403 ✅ # Run integration tests GATEWAY_URL=https://api.riotpiao.com \ AUTHENTIK_CLIENT_ID=xxx AUTHENTIK_CLIENT_SECRET=yyy \ go test -tags integration -v ./internal/serviceadapter # SQS JWT validation: reject without token ✅ # SQS JWT validation: accept with valid JWT ✅ ``` ## Architecture **Option B (Dumb Pipe):** - SQS: Gateway validates JWT (code unverified in kmsvc) - MinIO: Native OIDC/JWT (Phase 3.2) - Temporal: Native JWT via jwtKeyProvider (Phase 3.3) - Memory, IAM: Services validate their own JWTs **Key Design:** - JWKS cached with 15min TTL - Auto-refresh on key rotation (kid not found) - No token caching (always fresh state from JWKS) - 60s clock skew for exp/nbf - Returns 403 with error details for debugging