332 lines
12 KiB
Markdown
332 lines
12 KiB
Markdown
---
|
|
id: RAILIANCE-WP-0006
|
|
type: workplan
|
|
title: "Workload KV Access Lanes for ops-warden Fetch"
|
|
domain: financials
|
|
repo: railiance-platform
|
|
status: active
|
|
owner: codex
|
|
topic_slug: railiance
|
|
planning_priority: high
|
|
planning_order: 6
|
|
created: "2026-06-27"
|
|
updated: "2026-06-28"
|
|
depends_on_workplans:
|
|
- RAIL-PL-WP-0002
|
|
- RAILIANCE-WP-0004
|
|
related_state_hub_messages:
|
|
- "551031d1-335e-4db8-9535-820fea52d0a3"
|
|
state_hub_workstream_id: "96c8a93d-7a5a-4fa9-8f7b-865119551da3"
|
|
---
|
|
|
|
# RAILIANCE-WP-0006 - Workload KV Access Lanes for ops-warden Fetch
|
|
|
|
## Goal
|
|
|
|
Provision concrete, least-privilege OpenBao workload KV read lanes that
|
|
`ops-warden` can expose through `warden access --fetch` / `--exec` without
|
|
holding secret values itself.
|
|
|
|
The immediate request is for `whynot-design` to retrieve its npm publish token.
|
|
The path must be concrete, policy-scoped, and documented so the ops-warden
|
|
catalog can replace the current unresolved template path with a live
|
|
`whynot-design-npm-publish` entry.
|
|
|
|
No task in this workplan may paste, commit, log, or send secret values through
|
|
Git, State Hub, chat, prompts, or workplan text.
|
|
|
|
## Requirements Reviewed
|
|
|
|
Ops-warden message `551031d1-335e-4db8-9535-820fea52d0a3` asks
|
|
`railiance-platform` to provide non-secret pointers for:
|
|
|
|
- a concrete OpenBao KV path and field for `NPM_AUTH_TOKEN`;
|
|
- the KV mount used by the path;
|
|
- the OIDC login role for whynot-design or its operator identity;
|
|
- a read policy scoped to whynot-design's identity/service account;
|
|
- the flex-auth policy reference, if pre-approval is required.
|
|
|
|
Once these pointers are live, ops-warden will add a dedicated
|
|
`whynot-design-npm-publish` access catalog entry and a playbook, then notify
|
|
whynot-design.
|
|
|
|
## Proposed Contract
|
|
|
|
Use the workload credential convention documented in `docs/openbao.md`:
|
|
|
|
```text
|
|
platform/workloads/<tenant-or-org>/<workload>/<secret-purpose>
|
|
```
|
|
|
|
For this lane, the proposed non-secret contract is:
|
|
|
|
| Item | Proposed value |
|
|
| --- | --- |
|
|
| KV mount | `platform` |
|
|
| Tenant/org | `coulomb` |
|
|
| Workload/project | `whynot-design` |
|
|
| CLI path | `platform/workloads/coulomb/whynot-design/npm-publish` |
|
|
| KV-v2 policy data path | `platform/data/workloads/coulomb/whynot-design/npm-publish` |
|
|
| KV-v2 policy metadata path | `platform/metadata/workloads/coulomb/whynot-design/npm-publish` |
|
|
| Secret field | `NPM_AUTH_TOKEN` |
|
|
| OpenBao read policy | `workload-kv-read-whynot-design-npm-publish` |
|
|
| OIDC auth mount | `netkingdom` unless KeyCape compatibility requires `keycape` |
|
|
| OIDC role | `whynot-design-workload-kv-read` |
|
|
| Kubernetes auth role | `whynot-design-workload-kv-read` if an in-cluster service account consumes it |
|
|
| flex-auth ref | `secret.read:whynot-design` if tenant policy requires pre-approval |
|
|
|
|
The expected caller-facing read shape is:
|
|
|
|
```bash
|
|
bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
|
|
bao kv get -field=NPM_AUTH_TOKEN platform/workloads/coulomb/whynot-design/npm-publish
|
|
```
|
|
|
|
The command shape is illustrative only. Verification must avoid printing the
|
|
secret value; use attended operator checks or commands that prove read access
|
|
without persisting the token in logs.
|
|
|
|
## Tasks
|
|
|
|
## T01 - Capture ops-warden request and path contract
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0006-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "0c93496a-48bf-44e7-a75b-52e51e2639bc"
|
|
```
|
|
|
|
Record the ops-warden request, existing workload path convention, and proposed
|
|
whynot-design contract in this workplan.
|
|
|
|
Acceptance:
|
|
|
|
- The workplan names the concrete path, field, mount, policy, auth role, and
|
|
optional flex-auth ref needed by ops-warden.
|
|
- The plan distinguishes non-secret pointers from secret values.
|
|
- The plan keeps this workload KV read lane separate from
|
|
`RAILIANCE-WP-0005`, which tracks short-lived OpenBao token issuance for the
|
|
ops-warden signing smoke.
|
|
|
|
**2026-06-27:** Reviewed the unread ops-warden request and existing
|
|
`platform/workloads/<tenant-or-org>/<workload>/<secret-purpose>` convention.
|
|
Captured the proposed `whynot-design` npm publish lane above with no secret
|
|
values.
|
|
|
|
## T02 - Add least-privilege OpenBao read policy
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0006-T02
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "9c06d531-2566-4767-aa2f-8339605f23d5"
|
|
```
|
|
|
|
Create a concrete policy artifact for the whynot-design npm publish lane,
|
|
derived from `openbao/policies/workload-kv-read-template.hcl` but narrowed to
|
|
the selected `npm-publish` path.
|
|
|
|
Acceptance:
|
|
|
|
- A policy file under `openbao/policies/` defines read access to the exact
|
|
`platform/data/workloads/coulomb/whynot-design/npm-publish` path.
|
|
- Metadata/list capabilities are only as broad as needed for the caller and
|
|
ops-warden fetch UX.
|
|
- The policy grants no write, delete, patch, sudo, auth, or unrelated workload
|
|
capabilities.
|
|
- The policy name matches the pointer intended for ops-warden:
|
|
`workload-kv-read-whynot-design-npm-publish`.
|
|
|
|
**2026-06-27:** Added the concrete policy artifact at
|
|
`openbao/policies/workload-kv-read-whynot-design-npm-publish.hcl`. It grants
|
|
only `read` on the exact KV-v2 data and metadata paths for
|
|
`platform/workloads/coulomb/whynot-design/npm-publish`; it does not grant
|
|
write/delete/list/sudo/auth or sibling workload access. Added
|
|
`scripts/openbao-apply-workload-kv-lanes.sh`,
|
|
`make openbao-workload-kv-lanes-dry-run`, and
|
|
`make openbao-configure-workload-kv-lanes` for the source-owned policy apply
|
|
step. Dry-run passed. A live apply attempt with
|
|
`OPENBAO_WORKLOAD_KV_ARGS=--use-token-helper` reached unsealed OpenBao but was
|
|
denied with `403 permission denied` while writing the policy, so live policy
|
|
application waits on an approved platform-admin/operator token or a narrow
|
|
token-helper capability.
|
|
|
|
**2026-06-28:** Using the temporary operator token provided outside the repo,
|
|
Codex applied/confirmed the live policy in OpenBao. The verification read of the
|
|
policy succeeded and no secret values were printed or recorded.
|
|
|
|
## T03 - Define and apply auth bindings
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0006-T03
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "a217371a-0f85-40c6-b691-ac67834c86b5"
|
|
```
|
|
|
|
Define the auth role that lets whynot-design or an approved operator identity
|
|
read the lane as itself.
|
|
|
|
Acceptance:
|
|
|
|
- The OIDC login role is documented as
|
|
`bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read`,
|
|
or a different approved role is recorded with the reason.
|
|
- The role attaches only the whynot-design npm publish read policy.
|
|
- If an in-cluster whynot-design service account consumes the token, the
|
|
Kubernetes auth role binds only the approved namespace and service account.
|
|
- Compatibility with the legacy `keycape` auth mount is either configured or
|
|
explicitly declined.
|
|
|
|
**2026-06-27:** Documented the intended OIDC role pointer as
|
|
`auth/netkingdom/role/whynot-design-workload-kv-read` in
|
|
`docs/workload-kv-access-lanes.md`. Live application is waiting on confirmation
|
|
of the KeyCape/NetKingdom whynot-design bound claim or approved service-account
|
|
subject; do not create an unbounded OIDC role.
|
|
|
|
**2026-06-28:** Created/confirmed
|
|
`auth/netkingdom/role/whynot-design-workload-kv-read` with
|
|
`groups=["whynot-design"]`, only the
|
|
`workload-kv-read-whynot-design-npm-publish` policy, `ttl=15m`, and the approved
|
|
browser/local CLI callback URIs.
|
|
|
|
**2026-06-28:** Positive verification found the OIDC role was missing
|
|
`oidc_scopes`, causing OpenBao login to fail with `groups claim not found`.
|
|
Updated the live role and source CCR to request `openid`, `profile`, `email`,
|
|
and `groups`, matching the platform-admin OIDC scope shape.
|
|
|
|
## T04 - Provision the KV path without exposing the token
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0006-T04
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "c43724a3-c83e-4ab6-b7d1-e427fd93a9a9"
|
|
```
|
|
|
|
Have an approved operator create or confirm the OpenBao KV entry for the npm
|
|
publish token.
|
|
|
|
Acceptance:
|
|
|
|
- The path exists at
|
|
`platform/workloads/coulomb/whynot-design/npm-publish`.
|
|
- The field is named exactly `NPM_AUTH_TOKEN`.
|
|
- The token value is entered through an approved operator/OpenBao path and is
|
|
never written to Git, State Hub, chat, prompts, shell history, or workplan
|
|
text.
|
|
- Non-secret evidence records only the path, field name, actor, timestamp,
|
|
policy name, and verification result.
|
|
|
|
**2026-06-27:** The concrete path and field are now documented. Live secret
|
|
provisioning is waiting on an approved operator/OpenBao custody path for the
|
|
actual `NPM_AUTH_TOKEN` value.
|
|
|
|
**2026-06-28:** Confirmed the OpenBao metadata at
|
|
`platform/workloads/coulomb/whynot-design/npm-publish` includes
|
|
`catalog-id=whynot-design-npm-publish` and that the `NPM_AUTH_TOKEN` field is
|
|
present. The value was not printed, recorded, or copied into Git, State Hub,
|
|
chat, or workplans.
|
|
|
|
## T05 - Verify caller-scoped fetch behavior
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0006-T05
|
|
status: progress
|
|
priority: high
|
|
state_hub_task_id: "dc1f470b-e78a-48a9-9957-965aed47861f"
|
|
```
|
|
|
|
Prove that the authorized identity can read the token through the intended
|
|
OpenBao path and that unauthorized identities cannot.
|
|
|
|
Acceptance:
|
|
|
|
- An approved whynot-design identity or operator role can authenticate and
|
|
perform the fetch without unresolved `<...>` placeholders.
|
|
- Negative verification shows a non-whynot identity cannot read the path.
|
|
- Verification output contains no token value.
|
|
- OpenBao audit evidence exists for the authorized read and denied read, with
|
|
only non-secret request ids/timestamps recorded in the workplan or State Hub.
|
|
|
|
**2026-06-27:** Verification is waiting on live policy/role application and
|
|
secret provisioning. The runbook requires positive and negative fetch evidence
|
|
without printing the token value.
|
|
|
|
**2026-06-28:** Non-secret operator checks now pass for policy, auth role,
|
|
metadata, and field presence. Remaining verification is the attended
|
|
whynot-design OIDC positive check and a non-whynot denial check, both without
|
|
printing the token.
|
|
|
|
## T06 - Coordinate ops-warden catalog activation
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0006-T06
|
|
status: progress
|
|
priority: high
|
|
state_hub_task_id: "8e84ec19-01db-4baf-a532-de87e51d4994"
|
|
```
|
|
|
|
Send ops-warden the non-secret pointers needed to create and activate its
|
|
dedicated access catalog entry.
|
|
|
|
Acceptance:
|
|
|
|
- The State Hub reply to ops-warden includes only path, field, KV mount,
|
|
OIDC role, policy name/path, optional flex-auth ref, and runbook location.
|
|
- Ops-warden confirms the `whynot-design-npm-publish` catalog entry no longer
|
|
contains unresolved placeholders.
|
|
- `warden access "npm auth token" --fetch` or the agreed exact selector resolves
|
|
to the whynot-design lane and proxies the read as the caller.
|
|
- ops-warden confirms it holds no token value and only proxies OpenBao access.
|
|
|
|
**2026-06-27:** Added `docs/workload-kv-access-lanes.md` with the non-secret
|
|
handoff payload for ops-warden and sent the pointers by State Hub message. The
|
|
entry should remain draft/non-active until live OpenBao provisioning and
|
|
verification complete.
|
|
|
|
**2026-06-28:** The generic `openbao-api-key` ops-warden access lane can proxy
|
|
the check with explicit `--path` and `--field`, but the dedicated
|
|
`whynot-design-npm-publish` route is not yet present in the ops-warden routing
|
|
catalog. Keep activation pending until caller verification and catalog update.
|
|
|
|
## T07 - Decide whether to batch sibling workload-KV requests
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0006-T07
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "0b3ab5f5-e933-41f2-b29a-ab4ac50593aa"
|
|
```
|
|
|
|
Ops-warden noted similar still-open access lanes for
|
|
`issue-core-ingestion-api-key` and `openrouter-llm-connect`. Decide whether to
|
|
batch those paths in the same provisioning pass or keep this workplan scoped to
|
|
whynot-design.
|
|
|
|
Acceptance:
|
|
|
|
- The decision is recorded without secret values.
|
|
- If batching is approved, add concrete sub-tasks or a follow-up workplan for
|
|
each additional lane.
|
|
- If batching is deferred, notify ops-warden that this workplan will deliver
|
|
whynot-design first and leave the sibling entries for separate planning.
|
|
|
|
**2026-06-27:** Initially deferred sibling lanes (`issue-core-ingestion-api-key`
|
|
and `openrouter-llm-connect`) so the whynot-design npm token request could be
|
|
serviced first. The later ops-warden batch follow-up is now represented as
|
|
proposed CCRs in `RAILIANCE-WP-0007`, still unapproved and unresolvable until
|
|
human review and verification.
|
|
|
|
## Exit Criteria
|
|
|
|
- The whynot-design npm publish token has a concrete OpenBao KV path, field,
|
|
read policy, and auth role.
|
|
- The authorized caller can fetch the token as itself through OpenBao and
|
|
ops-warden without ops-warden storing the value.
|
|
- Unauthorized reads are denied.
|
|
- ops-warden has enough non-secret pointers to activate
|
|
`whynot-design-npm-publish`.
|
|
- No secret values appear in Git, State Hub, chat, prompts, logs, or workplans.
|