ops-warden/history/2026-08-19-flex-auth-caller-identity-evidence.md
tegwick 661176e37a
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Retire CoulombCore references; correct the 16443 diagnosis
CoulombCore is being retired, so the docs stop using it as the reference host:
state-hub-coulombcore examples become state-hub-railiance01, and the reuse-surface
playbook no longer attributes bao.coulomb.social to it — that resolves to
92.205.62.239, which is railiance01. The openrouter lane keeps its factual note
about ESO on the CoulombCore cluster, with a retirement flag for its owner.

Also corrects this session's own error. The WP-0031 evidence blamed the
Unauthorized on a local-port collision between k3s-api-coulombcore and
k3s-api-haskelseed. That was wrong: the haskelseed tunnel is a reverse forward,
where local_port is a destination rather than a listener, so they never competed.
16443 was simply CoulombCore's k3s — a different cluster whose client CA does not
know that cert. The wrong reason had already gone to flex-auth, so it is
corrected in the file rather than quietly dropped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:31:41 +02:00

92 lines
3.8 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. Use `--kubeconfig ~/.kube/config-railiance01`.
`~/.kube/config` / `config-hosteurope` — which `.bashrc` exports as `KUBECONFIG`
— points at `16443`, and that was **CoulombCore's** k3s API, a different cluster
whose client CA does not know this cert. Hence `Unauthorized`. CoulombCore is
being retired and that tunnel was removed on 2026-08-19, so the port is simply
gone now; `KUBECONFIG` was repointed at `config-railiance01`.
*(An earlier revision of this file blamed a local-port collision between
`k3s-api-coulombcore` and `k3s-api-haskelseed`. That was wrong: the haskelseed
tunnel is a **reverse** forward, where `local_port` is the destination on this
workstation rather than a listener, so the two never competed for the port. The
correction is recorded here because the wrong reason was also sent to flex-auth
and would have misdirected whoever followed the handoff.)*
## 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`.