PHASE 8 COMPLETE (10/10 tasks): - 8.2: X-Service/X-Resource dispatcher ✅ - 8.10: Phase gate - all 5 services routing ✅ Architecture decisions documented: - Gateway = dumb pipe (Option B) - SQS: gateway validates JWT (code unverified) - MinIO, Temporal: native JWT support - Memory, IAM: service-owned validation - ConfigMap-based config with Stakater Reloader - Real integration tests with cluster services PHASE 3 (Auth) TASKS CREATED (0/3 TODO): - 3.1: SQS JWT validation vs Authentik JWKS - 3.2: MinIO native JWT load-test - 3.3: Temporal JWT jwtKeyProvider configuration Updates: - tasks/8.2-x-service-dispatcher.md: marked GREEN - tasks/8.10-serviceadapter-gate.md: marked GREEN with notes - tasks/3.1-3.3: new Phase 3 auth tasks - tasks/INDEX.md: Phase 8 complete, Phase 3 active
65 lines
2.3 KiB
Markdown
65 lines
2.3 KiB
Markdown
# 3.1 — SQS: Gateway JWT validation against Authentik JWKS
|
|
|
|
Phase: 3 — Authentication & Authorization
|
|
Stage: TODO
|
|
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).
|
|
|
|
## Requirements
|
|
|
|
- [ ] 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
|
|
|
|
## Implementation
|
|
|
|
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`
|
|
|
|
## Verification
|
|
|
|
```bash
|
|
# Get JWT from Authentik
|
|
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/
|
|
|
|
# Should 403
|
|
curl -w '%{http_code}' -H 'X-Service: sqs' -H 'X-Resource: send-message' \
|
|
https://api.riotpiao.com/
|
|
# expected: 403
|
|
```
|
|
|
|
## Notes
|
|
|
|
- **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)
|