verify-reuse-surface-hub-writer.py logs in with skip_browser=true and shows the address (or opens a fresh temporary browser profile), so the default Authelia session is never reused. The receipt records uid, openbao_error and assurance per net-kingdom/docs/sign-in-diagnosis.md, with tokens, codes and emails redacted. Capabilities come from sys/capabilities-self on the lane token; no operator or root token is read. Needs railiance-platform CCR-2026-0045 applied to run live. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 1041694@bnt-lap001 Assistant-Session: 7af0bb68-ac4a-4ce3-8639-24ddd84c0b52
188 lines
9.3 KiB
Markdown
188 lines
9.3 KiB
Markdown
---
|
|
id: reuse-surface-hub-writer
|
|
demand_source: the-custodian/workplans/CUST-WP-0081 and State Hub message 08b254af-59d4-4d1a-9544-fed3dcaaf213
|
|
consumer_repo: reuse-surface
|
|
credential_type: openbao-oidc-kv-read
|
|
status: draft
|
|
approved_by: null
|
|
approved_at: null
|
|
created: "2026-10-14"
|
|
updated: "2026-10-14"
|
|
filed_as: CCR-2026-0044
|
|
---
|
|
|
|
# Construction plan: dedicated reuse-surface hub-writer caller
|
|
|
|
## 1. Demand
|
|
|
|
CUST-WP-0081 needs to register reviewed capabilities at the reuse-surface hub.
|
|
The write bearer already exists at
|
|
`platform/workloads/reuse/reuse-surface/runtime-secrets`, field
|
|
`REUSE_SURFACE_TOKEN`, delivered to the hub by External Secrets under
|
|
CCR-2026-0005. `warden access reuse-surface-hub-write-token --exec` is the
|
|
attended fetch. On 2026-10-14 that fetch returned OpenBao HTTP 403 after
|
|
flex-auth decision `decision:f730e3da14beebdd`. The helper did not run.
|
|
|
|
The operator then confirmed OpenBao CLI entity
|
|
`4a1f663c-0621-0483-edd0-f852274f4b6b` carries `default`, `operator-custody`
|
|
and `platform-admin`. `bao token capabilities` on that token reports
|
|
create, delete, list, read and update on the exact data path, the exact
|
|
metadata path, and an unrelated sibling. That token is not a dedicated
|
|
caller. OpenBao adds entity policies to every token for the entity, so
|
|
attaching `workload-kv-read-reuse-surface-runtime` to this entity would not
|
|
produce a token that carries only that policy. The request forbids that
|
|
attachment and forbids sending any secret value.
|
|
|
|
## 2. Existing-structure survey
|
|
|
|
Live `plan-survey.py` was not run. There is no `ops-mason-survey` grant in
|
|
this session, and the admin token must not be used as the survey credential.
|
|
This section is from the repositories on disk at 2026-10-14.
|
|
|
|
- Policy `workload-kv-read-reuse-surface-runtime`
|
|
(`railiance-platform/openbao/policies/workload-kv-read-reuse-surface-runtime.hcl`)
|
|
grants read on the exact data path and the exact metadata path. It grants
|
|
nothing else. Sibling denial is the absence of any other grant. No auth
|
|
role in railiance-platform names this policy.
|
|
- ESO uses the separate policy `workload-kv-read-reuse-surface-runtime-eso`
|
|
and Kubernetes role `reuse-surface-runtime-eso` (CCR-2026-0005, updated
|
|
2026-09-05). That lane is the hub pod's delivery path, not the workstation
|
|
caller.
|
|
- `agent-high-risk-boundary` denies data read and allows metadata read on
|
|
this path for tokens that carry it. `platform-admin` grants `platform/*`.
|
|
A token with both would be denied on the data path, because deny wins.
|
|
The reported capability set does not include deny, so the 403 and the
|
|
capability report are not the same effective token. The verifier must
|
|
measure the token that `warden access` will actually use.
|
|
- Catalog entry `reuse-surface-hub-write-token` is active and
|
|
`resolvable: true`. Its `auth_method` says the caller's own OpenBao token,
|
|
either operator OIDC or a token carrying the workload policy. It does not
|
|
name a role or an entity. CCR-2026-0005 does not name one either.
|
|
- Redirects that use `https://bao.coulomb.social` are stale. The public
|
|
ingress is gone. Fluid-telegram's role uses localhost, 127.0.0.1:8250, and
|
|
the 127.0.0.1:18200 tunnel.
|
|
|
|
**Does an existing lane already satisfy this demand?** The KV path and the
|
|
read policy do. The caller binding does not. The change is a role bound to
|
|
a different principal, plus the two self-lifecycle stanzas the platform
|
|
generator emits for `token_self_lifecycle: true`. No new secret, no new KV
|
|
path, no change to the ESO role.
|
|
|
|
## 3. Proposed changes
|
|
|
|
SEC-DSM §37, in order:
|
|
|
|
- Q1. The hub still requires its existing bearer. Reading that bearer from
|
|
OpenBao can use a person or service identity. Do not create a secret to
|
|
stand in for the caller.
|
|
- Q2. OpenBao accepts OIDC on `auth/netkingdom`. Use that. A KeyCape group
|
|
selects the principal. The principal's OpenBao entity must not be
|
|
`4a1f663c-0621-0483-edd0-f852274f4b6b` and must not carry `platform-admin`
|
|
or `operator-custody`. The uuid `f94b7c34-e151-30bb-b473-df3ccdbb9bf1` is
|
|
not an OpenBao entity.
|
|
- Q3. The OpenBao token is a 15-minute service token from the role. The hub
|
|
bearer stays the static field already in KV. No new issuance layer.
|
|
- Q4. Rotation of the hub bearer stays CCR-2026-0005. This plan does not
|
|
rotate it.
|
|
- Q5. No new persistent secret. Owner of the binding is railiance-platform.
|
|
The consumer is the attended hub-registration helper. Authority is the
|
|
OIDC role. Delivery is `warden access --exec` with the lane token.
|
|
Revocation is `auth/token/revoke-self` and deletion of the role.
|
|
|
|
Preference hierarchy: federated identity for the read, existing vaulted
|
|
static bearer for the hub. Not a new static secret and not a new AppRole.
|
|
|
|
1. `modify` policy `workload-kv-read-reuse-surface-runtime`. Add
|
|
`auth/token/lookup-self` read and `auth/token/revoke-self` update. Leave
|
|
the two KV paths as read. Do not add a glob deny: in OpenBao a deny on a
|
|
prefix also denies the more specific path. Sibling denial remains "not
|
|
granted", checked on a parent path and on
|
|
`platform/data/workloads/issue-core/issue-core/issue-core-runtime`.
|
|
2. `create` OIDC role `auth/netkingdom/role/reuse-surface-hub-writer-workload-kv-read`.
|
|
`token_policies` is only the workload policy, `token_no_default_policy` is
|
|
true, TTL 15m, max 30m, group `reuse-surface-hub-writers`, assurance
|
|
`aal2`. Callbacks are the workstation URIs above.
|
|
3. `create` KeyCape group `reuse-surface-hub-writers` with member
|
|
`bernd.worsch-3`. The OpenBao entity is created on first login. The
|
|
member receipt rejects the admin entity and any token that also carries
|
|
`platform-admin` or `operator-custody`.
|
|
4. No KV write. No attachment of this policy, or of
|
|
`workload-kv-read-reuse-surface-runtime-eso`, to entity
|
|
`4a1f663c-0621-0483-edd0-f852274f4b6b`.
|
|
|
|
Artifacts: `builds/reuse-surface-hub-writer/`. The CCR id is a draft.
|
|
railiance-platform assigns the real id and applies it. ops-mason does not
|
|
install the policy or the role.
|
|
|
|
## 4. Review notes
|
|
|
|
The 403 is not evidence that the path is closed to every token. It is
|
|
evidence that the token `warden access` used could not read the field.
|
|
The later capability check describes a different, broader token. The member
|
|
receipt has to show both facts on one token: exact policy set, and deny on
|
|
a sibling. A pass on the admin entity is a failure.
|
|
|
|
`credential-change.py` will not keep a hand-written `sys/capabilities-self`
|
|
stanza. The verifier therefore asks `sys/capabilities` with the operator
|
|
token and puts the lane token only in a mode-0600 body file that it
|
|
deletes. The receipt never contains the token.
|
|
|
|
Superseded by NK-WP-0051-T06 (MASON-WP-0012): railiance-platform now
|
|
generates the grant from `openbao.token_capabilities_self` (CCR-2026-0045),
|
|
and the verifier calls `sys/capabilities-self` with the lane token only.
|
|
|
|
Catalog `reuse-surface-hub-write-token` stays active. This plan does not
|
|
ask ops-warden to vend the value. After both verifier modes pass, ops-warden
|
|
can name the role in `auth_method`. Until then the entry's caller is unnamed
|
|
and the draft front door stays `pending-review`.
|
|
|
|
## 5. Attended apply and proof
|
|
|
|
Founder, after platform-operator and reuse-surface-owner approval, and after
|
|
key-cape confirms the group:
|
|
|
|
1. Copy the policy file over
|
|
`railiance-platform/openbao/policies/workload-kv-read-reuse-surface-runtime.hcl`
|
|
and apply the CCR with the delegated applier. Do not run `bao kv put`.
|
|
2. The capability query uses the first local token allowed to call
|
|
`sys/capabilities`: `BAO_TOKEN` or `VAULT_TOKEN`, then
|
|
`~/.local/openbao/platform-admin.token`, then `~/.vault-token`.
|
|
In a private window, as the group member:
|
|
|
|
```bash
|
|
python3 scripts/verify-reuse-surface-hub-writer.py member
|
|
python3 scripts/verify-reuse-surface-hub-writer.py non-member
|
|
```
|
|
|
|
3. Receipts are mode 0600 under
|
|
`~/.local/state/railiance/receipts/reuse-surface-hub-writer-*.txt`.
|
|
Copy the sanitized text into
|
|
`docs/evidence/` only after both results are `pass`. That copy is the
|
|
verification receipt. It is not written in advance.
|
|
4. Reply to message `08b254af` with the receipt text. Then a registration
|
|
command may use the same role's unprinted token:
|
|
|
|
```bash
|
|
warden access reuse-surface-hub-write-token --exec --field REUSE_SURFACE_TOKEN -- <silent helper>
|
|
```
|
|
|
|
Set `BAO_TOKEN` to the lane token for that one command. Do not use `--fetch`.
|
|
Do not export the field. Revoke the lane token when the command returns.
|
|
|
|
## 6. Result
|
|
|
|
Applied 2026-10-14T17:47:43Z. Both attended receipts passed on 2026-10-14.
|
|
Member at 20:05:45Z is entity `c204099b-cb94-363f-e207-5ff4d4aa6e94` with
|
|
only `workload-kv-read-reuse-surface-runtime`. Non-member at 20:10:49Z was
|
|
refused. Copies are in `docs/evidence/2026-10-14-reuse-surface-hub-writer-member.txt`
|
|
and `docs/evidence/2026-10-14-reuse-surface-hub-writer-non-member.txt`.
|
|
|
|
2026-10-14: railiance-platform filed this bundle as proposed CCR-2026-0044
|
|
(`88b4aed`, message `14e23602`). The live policy file stays as it was until
|
|
apply. The founder created LLDAP group `reuse-surface-hub-writers` with
|
|
member `bernd.worsch-3`. On 2026-10-14 that user enrolled a second factor.
|
|
`tegwick` is not the member. The founder reported uuid
|
|
`f94b7c34-e151-30bb-b473-df3ccdbb9bf1`. OpenBao has no entity with that id
|
|
and no entity named `bernd.worsch-3`. CCR-2026-0044 is approved in
|
|
railiance-platform `8655857`, with the group and `aal2` binding confirmed.
|
|
A passing login still has to present `/assurance/level=aal2`.
|