ServiceAdapter dispatcher currently ignores auth.required: true in adapter config. Wire JWT validation into dispatcher so per-adapter auth enforcement works.
Current state
Config declares auth.required: true on SQS adapter, but serviceadapter.Dispatcher.Dispatch() never calls jwtValidator. Only /v1/* paths enforce JWT today (in proxy.go).
Why
X-Service routing bypasses the /v1/* auth check entirely. Any pod that can reach gateway on port 8080 can call X-Service: sqs with no credentials. NetworkPolicy limits this to known namespaces, but defense in depth requires auth at the application layer too.
Acceptance Criteria
Dispatcher checks auth.required per adapter config
If required, validates Bearer JWT from Authorization header
Checks capability matching adapter service name (e.g. sqs:read, sqs:write)
Capability mapping: GET methods need <service>:read, POST/PUT/DELETE need <service>:write
No double-validation (gateway auth + downstream auth on same token)
## Summary
ServiceAdapter dispatcher currently ignores `auth.required: true` in adapter config. Wire JWT validation into dispatcher so per-adapter auth enforcement works.
## Current state
Config declares `auth.required: true` on SQS adapter, but `serviceadapter.Dispatcher.Dispatch()` never calls `jwtValidator`. Only `/v1/*` paths enforce JWT today (in proxy.go).
## Why
X-Service routing bypasses the `/v1/*` auth check entirely. Any pod that can reach gateway on port 8080 can call `X-Service: sqs` with no credentials. NetworkPolicy limits this to known namespaces, but defense in depth requires auth at the application layer too.
## Acceptance Criteria
- [ ] Dispatcher checks `auth.required` per adapter config
- [ ] If required, validates Bearer JWT from Authorization header
- [ ] Checks capability matching adapter service name (e.g. `sqs:read`, `sqs:write`)
- [ ] Capability mapping: GET methods need `<service>:read`, POST/PUT/DELETE need `<service>:write`
- [ ] Injects X-Forwarded-User headers (reuse P3.4 logic)
- [ ] Returns 401/403 with RFC 9457 problem detail
- [ ] Adapters with `auth.required: false` pass through unchanged
- [ ] Unit tests per adapter auth scenario
## Depends on
- P3.4 (identity header injection)
## Review checklist
- [ ] Memory/S3/IAM adapters stay auth-free (they validate internally)
- [ ] SQS adapter gets auth enforcement
- [ ] Temporal adapter stays auth-free (native JWT support)
- [ ] No double-validation (gateway auth + downstream auth on same token)
rock
added this to the Phase 3: OAuth2 Token Exchange & Identity Propagation milestone 2026-09-08 03:56:35 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
ServiceAdapter dispatcher currently ignores
auth.required: truein adapter config. Wire JWT validation into dispatcher so per-adapter auth enforcement works.Current state
Config declares
auth.required: trueon SQS adapter, butserviceadapter.Dispatcher.Dispatch()never callsjwtValidator. Only/v1/*paths enforce JWT today (in proxy.go).Why
X-Service routing bypasses the
/v1/*auth check entirely. Any pod that can reach gateway on port 8080 can callX-Service: sqswith no credentials. NetworkPolicy limits this to known namespaces, but defense in depth requires auth at the application layer too.Acceptance Criteria
auth.requiredper adapter configsqs:read,sqs:write)<service>:read, POST/PUT/DELETE need<service>:writeauth.required: falsepass through unchangedDepends on
Review checklist