Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a10391-6355-7b41-b0fa-3e14e874f091
225 lines
13 KiB
Markdown
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.
|