- Gateway validates SQS requests against Authentik JWKS - JWKS cached with 15min TTL, auto-refresh on key rotation - Verifies claims: iss, aud, exp, nbf, permissions - Returns 403 with error details on failure - Integration tests: reject without JWT, accept with valid JWT - All tests passing Phase 3 progress: 1/3 (next: 3.2 MinIO load-test)
2.5 KiB
2.5 KiB
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_URLKMSVC_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)
internal/auth/jwt.go: JWT validator with JWKS caching- Validates JWT signature against Authentik JWKS (RS256)
- Verifies claims: iss, aud, exp, nbf (60s skew)
- Checks
permissionsclaim for sqs:read/sqs:write/wildcard - Returns 403 with error details on failure
- JWKS cache: 15min TTL, auto-refresh on kid miss
- Wired into
internal/serviceadapter/router.gofor SQS - 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 & cachinggithub.com/golang-jwt/jwt/v5: JWT parsing & validation
Verification (Done)
# 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=<id>&client_secret=<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