Authenticate flex-auth calls with a rotating caller token

Closes the caller side of FLEX-WP-0015. FlexAuthHTTPAdapter reads the
audience-scoped projected ServiceAccount token from a file on every decision,
so hourly rotation needs no restart, and runtime configuration now requires
USER_ENGINE_FLEX_AUTH_TOKEN_FILE.

A missing, empty, or unreadable token file fails closed as a denial without
reaching flex-auth: OSError joins the caught set and an empty read raises.
Coverage proves all three unusable-token cases deny before any request is
made, and that neither the deny reason nor the decision repr carries the
token value.

Tenant-authority reads now identify user-engine as actor `user-engine` under
the protected tenant.read action, keeping tenant ids opaque and URL-encoded.

Contract: docs/flex-auth-caller-identity.md. Full suite: 148 tests, 3
provider-gated skips.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-18 10:53:31 +02:00
parent 6f6bbf5e4a
commit 4622b64061
7 changed files with 174 additions and 8 deletions

View file

@ -0,0 +1,54 @@
---
id: USER-WP-0023
type: workplan
title: "Bind user-engine to flex-auth with rotating workload identity"
domain: communication
repo: user-engine
status: active
owner: codex
topic_slug: netkingdom
created: "2026-08-18"
updated: "2026-08-18"
state_hub_workstream_id: "014d0886-b690-4860-8337-c718e440f678"
---
# USER-WP-0023 — flex-auth caller identity
Close the caller side of FLEX-WP-0015 without changing user-facing identity or
authorization semantics.
```task
id: USER-WP-0023-T01
status: done
priority: high
state_hub_task_id: "8dae0fe1-f8a0-4276-8ae3-fe1f5b410669"
```
Read the audience-scoped caller token from a file per authorization decision,
fail closed on rotation/read errors, and cover token rotation. Completed
2026-08-18; the full suite passes 143 tests with three provider-gated skips.
```task
id: USER-WP-0023-T02
status: done
priority: high
state_hub_task_id: "4a6c85e8-1ada-4147-b6b7-d340b7e5192c"
```
Align tenant-authority reads with the protected `tenant.read` action and actor
`user-engine`, preserving opaque URL encoding. Completed 2026-08-18 with
adapter request coverage.
```task
id: USER-WP-0023-T03
status: wait
priority: high
state_hub_task_id: "0499c65b-491d-4ed1-8549-f58dba48f612"
```
Promote together with the flex-auth A2 digest and the NetKingdom projected
ServiceAccount token manifest. Prove a valid caller succeeds, no token returns
401, and user-engine cannot represent another protected system. This is a live
operator rollout and was not performed by the source change.
Contract: `docs/flex-auth-caller-identity.md`.