user-engine/workplans/USER-WP-0037-hub-authority-lookup.md
tegwick ad501d032c
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
CUST-WP-0075: reconcile owner waits and decision routing
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a10391-6355-7b41-b0fa-3e14e874f091
2026-10-04 00:48:22 +02:00

225 lines
13 KiB
Markdown

---
id: USER-WP-0037
type: workplan
title: "Read-only account authority for Hub integration"
domain: communication
repo: user-engine
status: blocked
owner: codex
topic_slug: communication
created: "2026-09-28"
updated: "2026-10-03"
related:
- HUB-WP-0012
state_hub_workstream_id: "54d99faf-4c53-5927-a82c-feca41de2cf3"
---
# Hub authority lookup
Owner-side implementation for HUB-WP-0012. Source work is authorized; real
workload grants, root entitlements and deployment acceptance remain separate.
## Existing account lookup without provisioning
```task
id: USER-WP-0037-T01
status: done
priority: high
state_hub_task_id: "eb4c1a6c-3cf2-5195-9388-cb9db3190197"
```
Add an authorized service lookup for exact issuer/subject and scoped tenant.
Authorize the caller separately before target lookup. Unknown identities never
provision; return current global/scoped account state without roles or profile
PII. Preserve source observation time and identity/account references.
Implemented `UserEngineService.lookup_account_authority` with the separate
`account.authority.read` action and a digest-bound issuer/subject/tenant resource.
Caller identity is distinct from the target. Missing tenant-account state is
explicit `None`, not active. AccountAuthority contains no root grant, token roles
or profile/email data. Authorization denial may emit the existing audit record;
this operation does not provision or mutate domain records.
Validation: `make test` ran 270 tests successfully (eight optional skips), including
six new lookup checks; layer conformance passed. No HTTP endpoint, live grant or
production deployment was added. T02/T03 retain those outstanding owner gates.
## Root entitlement and mapping disposition
```task
id: USER-WP-0037-T02
status: done
depends_on: [NK-WP-0045-T05]
priority: high
state_hub_task_id: "23a5c211-277b-561e-a4b3-0f8e99537cac"
```
With NetKingdom, specify explicit current root-grant custody/revocation and
platform:root to tenant:platform mapping. Do not derive a grant from JWT roles,
a username, or Hub's configured root subject. Define retainable evidence for
account and entitlement observations.
Blocked 2026-09-28: this is a NetKingdom canon decision, not a user-engine
implementation choice. `net-kingdom/docs/platform-root-custody.md` covers
OpenBao/king-credential bootstrap custody but does not yet define how a
workload-facing root-grant fact is derived, represented, or revoked for a
consumer like the Hub. Requested via State Hub message
`379d266b-b738-4772-82c0-318e67a50bc8` to `net-kingdom`. `AccountAuthority`
deliberately still carries no root-grant field pending that decision.
2026-10-03 (CUST-WP-0075 inbox sweep): net-kingdom replied (message
`f1b61ee9`) with proposed NK-ADR-0017: the custody record is the sole root-grant
authority (LLDAP/JWT are projections, revocation is a recorded custody action);
the grant is relation `platform-root-custodian` in `tenant:platform` only,
`owner_system: net-kingdom-custody`; retainable evidence is subject, grant,
source record id+revision, observed_at, revoked_at/expires_at, cached at most
15 minutes, fail closed. No machine-readable read surface exists yet. user-engine
confirmed the mapping is sufficient (reply `60acf176`), stated the intended
optional `root_grant` observation shape and fail-closed behaviour, and asked
for exact (issuer, subject) keys and a monotonic revision. The wait moved from
`blocked_on: message-from:net-kingdom` to `depends_on` NK-WP-0045-T01 (founder
accepts or amends NK-ADR-0017) and NK-WP-0045-T04 (read-surface decision), both
routed to hub decision cef97ccd (packet D10). No code changed: the field is
added once the read surface exists; until then no root grant is returned.
2026-10-03 source-side progress (handoff `d6efcf93`): added transport-neutral
`src/user_engine/custody.py`. Injected source binding, owner read timestamp,
NetKingdom validation/transition/observation policy and atomic persistent baseline
interfaces; every observation performs a fresh owner read, including writes.
Read failures, stale/future data, rollback, same-revision mutations and persistence
conflicts yield no grant. Empty/revoked revisions retain the monotonic baseline.
Initial baseline establishment defaults denied and needs an approved bootstrap
procedure. No runtime binding or AccountAuthority root field is activated.
Approved OpenBao design envelope supplied by railiance-platform is
`data.data.document` containing the complete canon document. This is compatible
with the reader seam; the design approval does not establish an authenticated live source. This
repo contains no Kubernetes deployment/SA identity to use as an admission receipt.
Remaining owner requirements: version-pinned canon policy packaging, bounded
authenticated reader, atomic durable baseline store with controlled rebootstrap,
real read identity/provenance and denial/outage/recovery acceptance; then add the
optional AccountAuthority mapping and downstream integration receipts. T02 remains
`wait`, workplan remains `blocked`; local fixtures do not establish live delivery.
Founder approval received during this session: ADR-0017 and the proposed
OpenBao delivery design are approved; NK-WP-0045-T01/T04 no longer block T02.
This does not authorize live provisioning/deployment or create a custody entry.
The remaining dependency is NK-WP-0045-T05 owner delivery plus user-engine's
runtime admission, durable baseline, policy packaging and integration receipts.
Validation: `PYTHONDONTWRITEBYTECODE=1 make test` passed all 284 tests
(eight optional skips), including seven new cross-repo canon fixture checks;
layer conformance and `git diff --check` passed. The fixture tests optionally
load the sibling validator and skip if it or jsonschema is absent; production
has no dependency on a sibling checkout and no policy loader is configured.
Security orientation: emergent knowledge 0.2.3/start digest
`60f8811c6b94b30d357a0d9e5022f2a8ea52e69b47138d3a536755f3295310b5`,
withheld due to changed informed-decision source. Reviewed current local source
README plus current NetKingdom companion and custodian build guidance; restricted
work to offline source/tests, with no authority or live-readiness inference.
2026-10-03 continued go-forward implementation: the source is now complete for
the confirmed OpenBao/Kubernetes interface. Added dedicated projected-JWT login,
exact-path fresh KV reader (256 KiB; bounded timeout; denied redirects/cache hits;
safe errors), persistent PostgreSQL baseline compare-and-swap in the existing
database, optional AccountAuthority.root_grant and disabled-by-default runtime
configuration. Owner check time is sampled after I/O; returned observation retains
the canon-derived expires_at. Embedded validator/schema/provenance are pinned to
NetKingdom `db319335b27b61b855382ee5af5d690f06eeb010`, with schema lookup only
relocated. No sibling checkout dependency in the runtime.
Confirmed deployment source in `rapp-user-engine/manifests/runtime.yaml`: namespace
and ServiceAccount user-engine; existing flex-auth audience is not reused. Platform
agreed dedicated auth/kubernetes role user-engine-root-custody-reader, audience
openbao, no default policy and 60-second maximum token lifetime. The packaging
owner prepares the separate projected token and disabled overlay. No live grant,
credential provisioning or deployment acceptance is inferred from source changes.
`python -m user_engine.custody_bootstrap --expected-sha256 <publisher-digest>` is
the concrete controlled initialization tool: fresh authenticated read, exact
source/record binding and validated canonical JSON digest from a reviewed owner
receipt; initialize absent baseline once, never reset. Restore/source changes
require external producer audit/high-water reconciliation before reactivation.
Complete procedures and configuration: `docs/root-custody-runtime.md`.
Validation: full make test passed 296 tests (eight optional skips), with layer
conformance and diff checks passing; isolated disposable
PostgreSQL16 verified bootstrap CAS, competing-writer conflict and reconnect
persistence. Wheel build succeeded with embedded policy/schema/provenance. Offline
integration covers nested data.data.document to serialized AccountAuthority,
exact source/path/role mapping, post-read timing and emitted expires_at. No live
OpenBao or production database was accessed by these checks.
Founder reports no existing ceremony record; the approved initial document may
contain entries[] and therefore no grant. T02 remains wait for authenticated
publisher receipt (empty no-grant initialization is acceptable), platform reader admission,
owner image promotion, reviewed baseline initialization and live acceptance.
USER-WP-0037 stays blocked; T03 retains its independent Hub admission dependency.
2026-10-03 LIVE acceptance complete: producer admission/publication returned
ok=true for the approved empty revision1/KV1 document; controlled authenticated
receipt-bound baseline initialization succeeded. Actual consumer pod restart kept
the existing baseline with no reset/reinitialization. Fresh owner read matched;
wrong-audience login and real reader metadata LIST/sibling GET/custody POST were
denied. The internal fixture service harness against the actual live empty source
serialized root_grant:null; this is not a real admitted Hub caller acceptance.
Consumer-injected read failure/same-revision mutation retained the baseline.
Evidence: `docs/evidence/2026-10-03-root-custody-consumer-live.{md,json}`.
T02 is now done for delivered no-grant integration. No certified custodian or
actual grant was invented. Producer recovery/read-audit acceptance remains the
separate RPF-WP-0049/NK-WP-0045-T05 gate; T03 remains wait for real Hub credentials
and private integration. Workplan remains blocked solely on T03.
## Authenticated workload transport and private acceptance
```task
id: USER-WP-0037-T03
status: wait
blocked_on: message-from:state-hub
blocking_reason: "T02 delivered empty no-grant custody integration; real independently authenticated Hub caller credential admission and withdrawal/outage/private integration acceptance remain with state-hub (original f3bcc516; renewed request 350c3e12-284c-43a7-9ab1-116df8bcc007). Hub repository registration is not caller admission."
priority: high
state_hub_task_id: "c5d67725-c685-50f6-9db8-28114a34014b"
```
Expose a narrowly scoped read API with an independently authenticated Hub
workload, policy action account.authority.read, exact target binding and no
end-user bearer forwarding. Add HTTP schema and denial/no-provisioning tests,
then admit real caller credentials through their owner and verify withdrawal,
outages and private Hub integration. A service method alone is not this gate.
Implemented 2026-09-28: `POST /api/v1/platform/account-authority/lookup`
(`src/user_engine/web.py`), gated by a dedicated `hub_authority_caller` /
`hub_authority_token` pair distinct from `trusted_proxy_secret` and end-user
OIDC claims — a bearer mismatch or unconfigured route denies/404s before any
domain lookup runs. Wired in `runtime.py` behind
`USER_ENGINE_HUB_AUTHORITY_TOKEN` (+ `_ISSUER`/`_SUBJECT`/`_TENANT`), unset by
default so the route stays absent until provisioned. Schema, denial, and
no-provisioning tests: `tests/test_web_account_authority.py` (7 tests, all
green against `make test`, 277 tests total).
Blocked 2026-09-28 on the remaining half of this gate: admitting a *real*
Hub workload credential is a credential-routing matter
(`.claude/rules/credential-routing.md`) — OpenBao/ops-warden issue it, this
repo only consumes it. Requested via State Hub message
`f3bcc516-7241-4050-ba52-5723bb174936` to `state-hub`. Withdrawal, outage,
and private-integration verification with the real credential are still
owed once it exists.
2026-10-03 (CUST-WP-0075 inbox sweep): the net-kingdom reply (`f1b61ee9`)
does not bear on this task's own gate; the `message-from:net-kingdom`
qualifier was stale. The NetKingdom dependency is carried through
`depends_on: [USER-WP-0037-T02]`; the outstanding owner request is the
credential admission message `f3bcc516` to `state-hub`, still unanswered, so
the qualifier now names `state-hub`.
Source delivery receipt: implementation commit `0d0751d` pushed to main; image
CI is triggered by source changes, expected tag `main-0d0751d`; immutable digest030fe90232e20bb02b372e3d16b8ff659a5407d54f6405eb85754262b9ad7dc6
and owner rollout/restart receipts are now verified (see live consumer evidence). Empty owner candidate digest
`33a2ae086385028db1b654aa5646b7a98bcde1c5878c804e19315dadc3f87248`
is approved no-grant initialization input, not notice of live publication.
2026-10-04 CUST-WP-0075 reconciliation: `USER-WP-0037-T03`: Completed T02 no-grant integration edge removed. The live consumer receipt explicitly excludes actual admitted Hub principal acceptance; full filtered state-hub replies supply no T03 acceptance. Preserve message-from:state-hub pending exact admission/withdrawal/outage/private-integration evidence, renewed on original request thread as 350c3e12-284c-43a7-9ab1-116df8bcc007. No root grant, credential or private acceptance inferred from Hub record registration.