ops-warden/wiki/playbooks/catalog-lane-promotion.md
tegwick 98a2339b81
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
WARDEN-WP-0028: tenant secrets on mount tenants/ (first lane draft)
Adopt tenants/<tenant>/… custody (not platform/workloads). Document
onboarding, add draft binky-company-email-imap catalog entry, and mark
T01–T04/T06–T07 done. Founder Red provision remains T05.
2026-07-17 00:09:28 +02:00

5.1 KiB

Catalog Lane Promotion — draft → active

Date: 2026-07-01
Workplan: WARDEN-WP-0023 T05

registry/routing/catalog.yaml entries start as draft until an owner-confirmed concrete path exists. Draft lanes are hidden from default warden route find unless --all is passed.


Promotion checklist

Before changing status: draftstatus: active:

# Criterion Evidence
1 Owner confirmed Owner repo workplan or State Hub note naming the lane ready
2 Concrete path Real OpenBao path, grant id, or exec command — no unresolved <placeholders> in the primary handoff
3 Playbook wiki/playbooks/<id>.md with #worker-checklist section
4 Exec routing exec_owner + native command or exec_capable: true with tested warden access proxy
5 Resolvable warden route show <id> --json shows resolvable: true when placeholders are documented
6 Tests Routing test or smoke proving lookup + handoff shape (no secret values in fixtures)
7 Review date Update reviewed: in catalog entry
8 Verification Positive + negative proof via bao token capabilities — never bao kv get (see below)
9 Rotation guidance Secret-vending lanes carry a rotation: block; warden rotate-guide <id> returns steps. Enforced by the catalog_rotation_coverage scorecard check (WP-0026 T06)

Promotion PR touches: registry/routing/catalog.yaml, playbook, optional tests/test_routing.py, and a one-line note in wiki/CredentialRouting.md draft table.


Capabilities-safe lane verification (WARDEN-WP-0026 T01)

Verifying a lane must never read the secret data. A negative deny-test that runs bao kv get <path> will, if the deny fails (e.g. a privileged token fallback), print the secret value into a logged context — this is exactly the 2026-07-16 CCR-2026-0004 disclosure. Prove allow/deny with bao token capabilities, which returns the capability list, not the value.

For KV v2, capabilities are checked against the API data path (<mount>/data/<lane-path>), not the kv get logical path.

# Positive: the lane's own OIDC identity can read the data path.
bao login -method=oidc -path=netkingdom role=<lane-role>          # caller identity
bao token capabilities "$(bao print token)" platform/data/<lane-path>
#   → expect the list to include: read

# Negative: a default-only identity is denied — no value is ever read.
DEFAULT_TOKEN=$(bao token create -policy=default -field=token)     # if denied, STOP — do not fall back
bao token capabilities "$DEFAULT_TOKEN" platform/data/<lane-path>
#   → expect: deny
  • Never substitute bao kv get for the checks above. Reading a value to "confirm it's there" is the anti-pattern; presence is proven by read in the capability list.
  • If bao token create -policy=default is itself denied for your identity, that is a pass for the deny directiondo not fall back to your privileged login token to force the read.
  • Fetching a value for use (--field into an env var or file, or warden access … --field) is a separate, intended action — not verification.

Record the capability lists (allow/deny) as the promotion evidence; they contain no secret material and are safe for CCRs, State Hub, and Git.


Worked examples (already active)

ops-warden-warden-sign-token — promoted 2026-07-01 after RAILIANCE-WP-0005:

  • Owner: railiance-platform credential broker
  • Concrete grant: ops-warden/warden-sign
  • Playbook: wiki/playbooks/ops-warden-warden-sign-token.md
  • Smoke: make credential-exec-ops-warden-smoke

issue-core-ingestion-api-key — promoted 2026-07-02 after RAILIANCE-WP-0009 (CCR-2026-0002): KV path live, ExternalSecret issue-core/issue-core-runtime SecretSynced, positive + negative verification audit-logged.

openrouter-llm-connect — promoted 2026-07-02 after RAILIANCE-WP-0010 (CCR-2026-0003): KV path live, ExternalSecret activity-core/llm-connect-provider-secrets SecretSynced, llm-connect rolled out on the OpenBao-delivered value, positive + negative verification audit-logged.


Draft lanes (2026-07-17)

Catalog id Blocker
binky-company-email-imap Founder Red provision of IMAP values (CCR-2026-0007 applied; mount/policy/role live)
object-storage-sts NK-WP-0007 vending path not production-exercised
database-dynamic-credentials OpenBao database engine role paths TBD per workload

Promoted 2026-07-16: railiance-backup-offsite-lane — CCR-2026-0004 capabilities-safe re-verify (WP-0026 T07); primary field NC_WEBDAV_TOKEN; risk: high + EXPOSED taint on version 2 (operator may rotate optionally).

Tenant path (WP-0028): new client secrets use mount tenants/, not platform/workloads/. See wiki/playbooks/tenant-secret-onboarding.md.

Re-run promotion when the owning repo closes the blocker; do not promote on playbook prose alone.


See also

  • wiki/CredentialRouting.md — draft table index
  • wiki/playbooks/ops-warden-warden-sign-token.md — promotion reference