84 lines
3.2 KiB
Markdown
84 lines
3.2 KiB
Markdown
|
|
# flex-auth caller identity — live evidence (WARDEN-WP-0031 T04)
|
||
|
|
|
||
|
|
**Date:** 2026-08-19
|
||
|
|
**Pin:** `flex-auth-ops-warden`, railiance01 cluster, namespace `flex-auth`,
|
||
|
|
Service `flex-auth-ops-warden:8080`, digest `sha256:138aa347…`, running
|
||
|
|
`--caller-auth-mode warn --caller-kubernetes-url https://10.43.0.1
|
||
|
|
--caller-binding ops-warden=system:serviceaccount:ops-warden:ops-warden`
|
||
|
|
(read off the live Deployment, matching FLEX-WP-0016 T02).
|
||
|
|
|
||
|
|
Reached from the workstation by port-forward; the tunnel `k3s-api-railiance01`
|
||
|
|
(local `16444`) carries the API. Note `~/.kube/config` / `config-hosteurope`
|
||
|
|
points at `16443`, which two bridge tunnels claim
|
||
|
|
(`k3s-api-coulombcore` and `k3s-api-haskelseed`) — that collision is why a
|
||
|
|
`system:masters` cert returns `Unauthorized` there. Use
|
||
|
|
`--kubeconfig ~/.kube/config-railiance01`.
|
||
|
|
|
||
|
|
## Baseline — before
|
||
|
|
|
||
|
|
Unauthenticated `POST /v1/check` was **served**, and the pin logged:
|
||
|
|
|
||
|
|
```
|
||
|
|
caller authentication warning: caller is not authenticated
|
||
|
|
```
|
||
|
|
|
||
|
|
That is the whole reason `policy.enabled` could not flip: warn mode answers
|
||
|
|
anonymous callers, so nothing about the enforcing path was ever exercised.
|
||
|
|
|
||
|
|
## What was created
|
||
|
|
|
||
|
|
`deploy/kubernetes/caller-identity.yaml` — Namespace `ops-warden` and
|
||
|
|
ServiceAccount `ops-warden/ops-warden`, `automountServiceAccountToken: false`,
|
||
|
|
**no RBAC of any kind**. It is never used to call the Kubernetes API; it exists
|
||
|
|
only to be the subject of flex-auth's TokenReview. Applied 2026-08-19.
|
||
|
|
|
||
|
|
Cluster resources are railiance-platform's to own — this is an ADR-0003 interim
|
||
|
|
cover, and the manifest names that owner in its header.
|
||
|
|
|
||
|
|
## Token source
|
||
|
|
|
||
|
|
`policy.caller_auth.mode: command` in `~/.config/warden/warden.yaml`:
|
||
|
|
|
||
|
|
```
|
||
|
|
kubectl --kubeconfig ~/.kube/config-railiance01 create token ops-warden \
|
||
|
|
-n ops-warden --audience flex-auth --duration 10m
|
||
|
|
```
|
||
|
|
|
||
|
|
Audience `flex-auth` is required: `internal/callerauth/tokenreview.go` sends
|
||
|
|
`spec.audiences: ["flex-auth"]` and rejects an identity whose audiences do not
|
||
|
|
contain it. 900-char bound token, 10 minute TTL, minted per call, never stored.
|
||
|
|
|
||
|
|
## Evidence
|
||
|
|
|
||
|
|
```
|
||
|
|
$ python3 scripts/check_policy_caller_identity.py --url http://127.0.0.1:19090
|
||
|
|
✓ warden.yaml: loaded; policy.enabled=false
|
||
|
|
✓ caller_auth.mode: command
|
||
|
|
✓ caller token: obtained, 900 chars, sha256:e50da3ec6769
|
||
|
|
✓ live /v1/check: HTTP 200, effect=allow, decision=decision:f3f7c88f9585582a
|
||
|
|
READY
|
||
|
|
```
|
||
|
|
|
||
|
|
The decisive check is not that allow — warn would have allowed an anonymous
|
||
|
|
caller too. It is the warning count:
|
||
|
|
|
||
|
|
```
|
||
|
|
warnings before: 4
|
||
|
|
warnings after 2 authenticated gate runs: 4
|
||
|
|
```
|
||
|
|
|
||
|
|
The pin authenticated the caller and had nothing to warn about. That is the
|
||
|
|
condition ADHOC-2026-08-17-T01 required before `policy.enabled` may flip
|
||
|
|
anywhere.
|
||
|
|
|
||
|
|
## What is still open
|
||
|
|
|
||
|
|
`policy.enabled` stays **false**. The remaining sequence (T05) is flex-auth's
|
||
|
|
move first: `callerAuth.mode: enforce` on this pin (their FLEX-WP-0016 T03),
|
||
|
|
re-run the gate against the enforcing pin, then `policy.enabled: true` with
|
||
|
|
`fail_closed: true`, then an end-to-end `warden sign` — which additionally needs
|
||
|
|
a scoped `VAULT_TOKEN` via `ops-warden-warden-sign-token`.
|
||
|
|
|
||
|
|
Flipping before enforce buys nothing; flipping before this task would have
|
||
|
|
401'd every `warden sign`.
|