Implement inbound caller authentication (ADR 0004); close T03 and T05
TokenReview-based caller identity with audience-scoped tokens and exact resource.system to ServiceAccount bindings, per ops-warden's recommendation. Deletes the unwired tenant-engine live-roles adapter (T03) and adds make verify-posture (T05). Source implements A2; running digest is still A0 until promotion, so tenancy.current.A stays 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6d82ef7f14
commit
1e1e077b27
18 changed files with 768 additions and 357 deletions
65
docs/adr/0004-inbound-caller-authentication.md
Normal file
65
docs/adr/0004-inbound-caller-authentication.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# ADR 0004 — authenticate and bind authorization callers
|
||||
|
||||
Status: accepted (source implemented; production promotion pending)
|
||||
|
||||
Date: 2026-08-18
|
||||
|
||||
## Context
|
||||
|
||||
`POST /v1/check` and `/v1/batch_check` accepted an asserted subject, tenant and
|
||||
protected-system name from any workload with network reach. NetworkPolicy
|
||||
limited reachability but did not establish caller identity. A caller could
|
||||
therefore represent another protected system and obtain an authoritative
|
||||
decision under the wrong policy package.
|
||||
|
||||
The boundary must authenticate workloads without turning flex-auth into an
|
||||
identity issuer, sharing a long-lived secret between services, or coupling
|
||||
authorization availability to an unrelated identity-provider round trip.
|
||||
|
||||
## Decision
|
||||
|
||||
Use Kubernetes ServiceAccount tokens with audience `flex-auth`. flex-auth calls
|
||||
the Kubernetes TokenReview API through a separately projected reviewer token
|
||||
and binds the authenticated ServiceAccount principal to every
|
||||
`resource.system` in the request. Both the single and batch endpoints use the
|
||||
same choke point; health remains unauthenticated.
|
||||
|
||||
Each deployed policy instance has an explicit, exact binding. For example:
|
||||
|
||||
```text
|
||||
tenant-engine=system:serviceaccount:tenant-engine:tenant-engine
|
||||
user-engine=system:serviceaccount:user-engine:user-engine
|
||||
```
|
||||
|
||||
Unknown systems, missing or invalid tokens, audience mismatch and principal
|
||||
mismatch fail closed. TokenReview unavailability returns 503 rather than an
|
||||
authorization answer. Tokens and reviewer credentials are re-read rather than
|
||||
cached across rotation.
|
||||
|
||||
Three modes support promotion: `disabled`, `warn`, and `enforce`. Warn mode
|
||||
records the same authentication failures without logging credentials. It is a
|
||||
bounded migration aid, not a conformant steady state. The reviewed desired
|
||||
manifests select `enforce`; promotion still follows FLEX-WP-0011 and requires a
|
||||
new immutable image digest plus caller rollout evidence.
|
||||
|
||||
## Rejected alternatives
|
||||
|
||||
- NetworkPolicy alone proves network position, not workload identity.
|
||||
- A shared header secret has broad replay and rotation blast radius and cannot
|
||||
bind a Kubernetes workload principal.
|
||||
- Application mTLS would add a separate certificate lifecycle where the
|
||||
cluster already has short-lived projected workload identity.
|
||||
- Using the caller token itself to invoke TokenReview would grant callers an
|
||||
unnecessary API permission. A narrow reviewer ServiceAccount holds only
|
||||
`create` on `tokenreviews.authentication.k8s.io`.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Caller identity is bound once at the flex-auth ingress and cannot be swapped
|
||||
by changing request JSON.
|
||||
- flex-auth depends on the Kubernetes authentication API for uncached checks;
|
||||
an outage fails closed with 503.
|
||||
- Each new protected system needs an explicit binding and projected caller
|
||||
token. There is no wildcard binding.
|
||||
- Source and desired state reach A2, while the live declaration remains A0
|
||||
until the immutable digest is promoted and probed.
|
||||
Loading…
Add table
Add a link
Reference in a new issue