net-kingdom/workplans/NK-WP-0026-flex-auth-caller-identity-rollout.md
codex 82452d655f
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
fix(workplans): adopt ADR-007 derived identifiers for unregistered records
These workplans exist only in the retired local hub. Their random pre-ADR-007
identifiers are refused by C-06 as stale references, so they cannot be
registered. Deriving from the canonical record id takes no identity from
anything: central does not hold them and the old ids die with the cache.

Records central already holds were deliberately left untouched.

Refs CUST-WP-0068-T06

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 20:14:28 +02:00

5.1 KiB

id type title domain repo status owner topic_slug created updated state_hub_workstream_id
NK-WP-0026 workplan Promote user-engine workload identity to flex-auth infotech net-kingdom finished codex netkingdom 2026-08-18 2026-08-19 3e8965aa-494a-5dcf-a11d-b768c196c548

NK-WP-0026 — user-engine caller identity rollout

id: NK-WP-0026-T01
status: done
priority: high
state_hub_task_id: "294eb50e-2d54-59f1-a793-d10e53e33020"

Declare a non-automounted user-engine ServiceAccount and a one-hour projected token with audience flex-auth; mount only that token into the portal. Source completed 2026-08-18. Existing NetworkPolicy already permits only the named flex-auth user-engine instance on port 8080.

id: NK-WP-0026-T02
status: done
priority: high
state_hub_task_id: "d24461e9-c378-58ac-97ed-60ad6e563d47"

Both sides promoted and probed. Verified live on railiance01, 2026-08-19, by net-kingdom against the cluster rather than against another repo's assertion.

Deployed digests

Side Object Digest
user-engine deploy/user-engine (ns user-engine), pod user-engine-8569d7cb87-fp7px forgejo.coulomb.social/coulomb/user-engine@sha256:c501aeb204154d85017565a87fd34cff12e5c48f600d124d3f8c82f11bb9d59c
flex-auth deploy/flex-auth-user-engine (ns flex-auth), pod flex-auth-user-engine-b745b6b5c-zhsfv forgejo.coulomb.social/coulomb/flex-auth@sha256:138aa3471c46bca6e814691fa1e6520aedda3dffd743e6b09141ab433afdb64b

flex-auth serves with --caller-auth-mode enforce and --caller-binding user-engine=system:serviceaccount:user-engine:user-engine. The warn stage was run on flex-auth's side under FLEX-WP-0011 / FLEX-WP-0015-T02; net-kingdom observed the end state, not the intermediate warn window.

The T01 caveat is cleared. The old digest did not read the projected file. The deployed digest does: user_engine/runtime.py:45 makes USER_ENGINE_FLEX_AUTH_TOKEN_FILE a required setting (_required(...), so the portal cannot start without it), and user_engine/adapters/flex_auth.py:62-68 re-reads the file per decision — deliberately, so projected-token rotation needs no restart — and sends it as Authorization: Bearer. Both were read out of the running container, not out of the source tree.

ProbesPOST /v1/check against flex-auth-user-engine.flex-auth.svc.cluster.local:8080, run from inside the workload pods so NetworkPolicy and identity are exercised as in production. All are read-only decision queries; nothing in the cluster was mutated.

Probe Run from Credential Result
valid user-engine-8569d7cb87-fp7px the pod's own projected token, audience flex-auth HTTP 200, decision:d9aef25f08e17b84, effect: allow, reason: self_service, matched_rule: self_service, policy_version: v1
missing token user-engine-8569d7cb87-fp7px no Authorization header HTTP 401 unauthenticated
wrong system user-engine-8569d7cb87-fp7px valid user-engine token, body asserting resource.system: tenant-engine HTTP 403 forbidden
wrong system (network path) tenant-engine-6c6dcbddbb-4v26w tenant-engine's own projected token, against the user-engine PDP connection refused — NetworkPolicy denies the cross-service path before flex-auth sees it

Note on the wrong-system probe, because it differs from what flex-auth reported. flex-auth's tenancy.yaml states "a token bound to the other protected system returns 403". net-kingdom could not reproduce that literal case: the tenant-engine pod cannot reach the user-engine PDP at all (Errno 111), so the 403 never arises on that path. What is reproducible, and is the same substitution attack, is a caller authenticated as one system asserting another system in the request body — ADR-0004's stated threat, "a caller could represent another protected system" — and that returns 403. The estate position is therefore stronger than claimed (two independent layers refuse it), but the claimed evidence is not the evidence that exists. Recorded rather than smoothed.

Manifest drift, found and closed. sso-mfa/k8s/user-engine/runtime.yaml still pinned sha256:e3b5f65b… — the digest T01 warned must not be applied — while the cluster ran c501aeb2…. Anyone re-applying the repo's own manifest would have rolled the portal back to an image that does not read the token file, against a PDP now in enforce: every authorization call would 401 and the portal would fail closed. The manifest is now pinned to the deployed digest and kubectl diff -f sso-mfa/k8s/user-engine/runtime.yaml is empty, exit 0 — declared state and live state agree.

Observation routed to flex-auth, not a blocker. A syntactically invalid bearer token returns HTTP 503 caller authentication unavailable, not 401. ADR-0004 reserves 503 for TokenReview unavailability and puts invalid tokens with the 401 class. It fails closed either way, so there is no bypass, but a malformed credential is being reported as a flex-auth outage — which will mislead whoever reads the first page of an incident.