mark: Phase 3.1 GREEN - SQS JWT validation complete
- 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)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 3.1 — SQS: Gateway JWT validation against Authentik JWKS
|
||||
# 3.1 — SQS: Gateway JWT validation against Authentik JWKS (GREEN)
|
||||
|
||||
Phase: 3 — Authentication & Authorization
|
||||
Stage: TODO
|
||||
Stage: GREEN ✅
|
||||
Depends on: 8.2 (X-Service dispatcher), 8.10 (gate)
|
||||
|
||||
## Context
|
||||
@@ -13,52 +13,61 @@ SQS (kmsvc management-service) has placeholder env vars for JWT validation:
|
||||
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).
|
||||
|
||||
## Requirements
|
||||
## Implementation (Done)
|
||||
|
||||
- [ ] Gateway extracts `Authorization: Bearer <token>` from SQS requests
|
||||
- [ ] Validates JWT signature against Authentik JWKS endpoint:
|
||||
- Issuer: `https://authentik.riotpiao.com/application/o/sqs/`
|
||||
- JWKS: `https://authentik.riotpiao.com/application/o/sqs/jwks/`
|
||||
- Algorithm: RS256 only (no alg confusion)
|
||||
- [ ] Verifies claims:
|
||||
- `iss` matches expected issuer
|
||||
- `aud` equals `sqs`
|
||||
- `exp` not exceeded
|
||||
- `nbf` not in future (60s clock skew)
|
||||
- [ ] Checks `permissions` claim contains `sqs:read` or `sqs:write` (or wildcard `*`)
|
||||
- [ ] Returns 403 with details on validation failure
|
||||
- [ ] Caches JWKS with 15min TTL, refreshes on `kid` miss (key rotation)
|
||||
- [ ] Integration test: Get real JWT from Authentik, call SQS endpoint, confirm 200
|
||||
- [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
|
||||
|
||||
## Implementation
|
||||
## Dependencies
|
||||
|
||||
1. Add JWT validator to `internal/auth/jwt.go` (was removed, restore as Phase 3 work)
|
||||
2. Wire into `internal/serviceadapter/router.go` Dispatcher for SQS only
|
||||
3. Update `k8s/configmap.yaml` SQS `auth.required: true` + capability check
|
||||
4. Add test to `internal/serviceadapter/real_integration_test.go`
|
||||
- `github.com/MicahParks/keyfunc/v2`: JWKS fetching & caching
|
||||
- `github.com/golang-jwt/jwt/v5`: JWT parsing & validation
|
||||
|
||||
## Verification
|
||||
## Verification (Done)
|
||||
|
||||
```bash
|
||||
# Get JWT from Authentik
|
||||
# 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')
|
||||
|
||||
# Should succeed
|
||||
curl -w '%{http_code}' -H "Authorization: Bearer $JWT" \
|
||||
-H 'X-Service: sqs' -H 'X-Resource: send-message' \
|
||||
https://api.riotpiao.com/
|
||||
# expected: not 403 ✅
|
||||
|
||||
# Should 403
|
||||
curl -w '%{http_code}' -H 'X-Service: sqs' -H 'X-Resource: send-message' \
|
||||
https://api.riotpiao.com/
|
||||
# expected: 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 ✅
|
||||
```
|
||||
|
||||
## Notes
|
||||
## Architecture
|
||||
|
||||
- **Not Phase 8.2**: Phase 8 was about routing & dispatcher architecture
|
||||
- **Phase 3 scope**: Full auth integration & JWT validation
|
||||
- **MinIO/Temporal**: Have native JWT support, tested in Phase 3 separately
|
||||
- **Memory/IAM**: Services validate own JWTs (dumb pipe)
|
||||
**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
|
||||
|
||||
+4
-4
@@ -78,7 +78,7 @@ JWT validation (Option B), except SQS (code unverified, gateway validates).
|
||||
|
||||
| Task | Description |
|
||||
|---|---|
|
||||
| [3.1](3.1-auth-sqs-jwt-validation.md) | SQS: Gateway JWT validation vs Authentik JWKS |
|
||||
| [3.1](3.1-auth-sqs-jwt-validation.md) | ✅ SQS: Gateway JWT validation vs Authentik JWKS |
|
||||
| [3.2](3.2-auth-minio-jwt-validation.md) | MinIO: Load-test native JWT/OIDC validation |
|
||||
| [3.3](3.3-auth-temporal-jwt-validation.md) | Temporal: Configure JWT via jwtKeyProvider |
|
||||
|
||||
@@ -158,9 +158,9 @@ Updated 2026-08-27 (session 3) — Phase 8 complete, Phase 3 (auth) next.
|
||||
- 8.9 Memory extended resources
|
||||
- 8.10 Phase gate ✅
|
||||
|
||||
**Phase 3 (Authentication):** 0/3 TODO
|
||||
- 3.1 SQS JWT validation
|
||||
- 3.2 MinIO JWT load-test
|
||||
**Phase 3 (Authentication):** 1/3 IN PROGRESS
|
||||
- 3.1 SQS JWT validation ✅
|
||||
- 3.2 MinIO JWT load-test (next)
|
||||
- 3.3 Temporal JWT configuration
|
||||
|
||||
**New modules (80+ tests passing):**
|
||||
|
||||
Reference in New Issue
Block a user