railiance-platform/docs/workload-kv-access-lanes.md
tegwick 86209fa90c
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
CCR-2026-0007: binky IMAP on tenants/ mount + CCR allowlist
Enable tenant commercial secrets: applier accepts mount tenants/, apply
policy and OIDC role for company-email IMAP (metadata only; values are
founder Red provision). Extend agent-high-risk-boundary for the path.
2026-07-17 00:09:28 +02:00

14 KiB

Workload KV Access Lanes

This document records concrete OpenBao workload KV paths that external access front doors can reference without storing or vending secret values themselves. The first lane is for ops-warden warden access --fetch / --exec.

Safety Rules

  • Do not put secret values in Git, State Hub, chat, prompts, workplans, or logs.
  • Store only non-secret pointers here: path, field name, policy name, auth role, flex-auth reference, and verification status.
  • ops-warden may proxy a read as the caller, but it must not hold the returned value beyond the caller-requested fetch/exec process.
  • Live writes require an approved OpenBao/operator path and attended handling of the secret value.

whynot-design npm Publish Token

Ops-warden original request: 551031d1-335e-4db8-9535-820fea52d0a3

Ops-warden batch follow-up: fe5b1696-8956-4bd5-9d6f-dbde1901a076

Item Value
ops-warden catalog id whynot-design-npm-publish
Tenant/org coulomb
Workload/project whynot-design
KV mount platform
OpenBao CLI path platform/workloads/coulomb/whynot-design/npm-publish
Secret field NPM_AUTH_TOKEN
Front-door readiness active, resolvable=true in ops-warden
Read policy workload-kv-read-whynot-design-npm-publish
Policy file openbao/policies/workload-kv-read-whynot-design-npm-publish.hcl
OIDC auth mount netkingdom
OIDC role whynot-design-workload-kv-read
OIDC callback URIs https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback, http://localhost:8250/oidc/callback, http://127.0.0.1:8250/oidc/callback
Kubernetes auth role whynot-design-workload-kv-read if an in-cluster service account consumes this lane
flex-auth ref secret.read:whynot-design if tenant policy requires pre-approval

Expected caller login shape:

bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read

Expected OpenBao fetch shape:

bao kv get -field=NPM_AUTH_TOKEN platform/workloads/coulomb/whynot-design/npm-publish

Expected ops-warden exec shape after activation:

warden access whynot-design-npm-publish --exec -- npm publish

Ops-warden confirmed activation in State Hub message f76d3a9e-a98f-4081-885d-b79d94312699: selector whynot-design-npm-publish is active, resolvable, and wired to this caller-scoped lane. The sibling lanes issue-core-ingestion-api-key and openrouter-llm-connect remain draft and are tracked separately by RAILIANCE-WP-0009 and RAILIANCE-WP-0010.

The fetch command returns the secret value to the authenticated caller. Run it only in an attended shell or through a process that consumes the value without logging it.

OpenBao Policy

The source policy grants only:

read platform/data/workloads/coulomb/whynot-design/npm-publish
read platform/metadata/workloads/coulomb/whynot-design/npm-publish

It does not grant write, delete, patch, sudo, auth, sibling workload, or parent list capabilities.

Dry-run the policy apply path:

make openbao-workload-kv-lanes-dry-run

Apply the policy with an approved platform-admin/operator token:

OPENBAO_TOKEN_FILE=~/.local/openbao/platform-admin.token \
  make openbao-configure-workload-kv-lanes

If the OpenBao pod has an approved token-helper session, use:

make openbao-configure-workload-kv-lanes OPENBAO_WORKLOAD_KV_ARGS=--use-token-helper

Do not paste the token into shell history or logs. The helper reads a token from OPENBAO_TOKEN_FILE or an interactive hidden prompt unless --use-token-helper is set, and passes it to OpenBao through stdin.

Auth Role

The intended OpenBao OIDC role is:

auth/netkingdom/role/whynot-design-workload-kv-read

The role must attach only:

workload-kv-read-whynot-design-npm-publish

The OIDC role must include the browser and local CLI callback URIs accepted by OpenBao:

https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback
http://localhost:8250/oidc/callback
http://127.0.0.1:8250/oidc/callback

The role must request these OIDC scopes so KeyCape emits the group claim OpenBao checks:

openid
profile
email
groups

The whynot-design pilot claim is confirmed as groups=whynot-design. Before applying any changed role, re-confirm the KeyCape/NetKingdom claim that identifies the whynot-design caller. The role must bind to that claim; do not create an unbounded OIDC role that grants this policy to every OIDC user.

If the consumer is an in-cluster service account instead of an OIDC caller, use Kubernetes auth with the same role name and bind only the approved namespace and service account.

Secret Provisioning

An approved operator must create or confirm the secret with:

path:  platform/workloads/coulomb/whynot-design/npm-publish
field: NPM_AUTH_TOKEN

In the OpenBao UI, open the platform KV engine and create or edit the secret at:

workloads/coulomb/whynot-design/npm-publish

For policies and API checks, the same KV-v2 secret is addressed as:

platform/data/workloads/coulomb/whynot-design/npm-publish
platform/metadata/workloads/coulomb/whynot-design/npm-publish

The OpenBao UI path does not include the data/ or metadata/ segment. Those segments are the KV-v2 API and ACL policy paths.

The value must be entered directly through OpenBao/operator custody. Record only non-secret evidence: actor, timestamp, path, field name, policy name, and verification result.

Verification

Positive verification:

  1. Authenticate as the whynot-design caller using the approved OIDC or Kubernetes auth role.
  2. Fetch the field in an attended session or through warden access --exec.
  3. Record only that the fetch succeeded; do not record the value.

Safe attended command shape before the dedicated ops-warden catalog id is activated:

set +x
bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
warden access "npm token" \
  --path platform/workloads/coulomb/whynot-design/npm-publish \
  --field NPM_AUTH_TOKEN \
  --no-policy \
  --exec -- sh -lc 'test -n "$NPM_AUTH_TOKEN"'

Use --no-policy only while the local ops-warden config reports policy.enabled=false; remove it once the flex-auth gate is enforced. If login fails with groups claim not found, the OpenBao role is missing the groups OIDC scope and must be corrected before retrying.

Negative verification:

  1. Authenticate as a non-whynot identity.
  2. Confirm the same field read is denied.
  3. Record the non-secret OpenBao audit request ids or timestamps for the allowed and denied attempts.

ops-warden Handoff

Send ops-warden only these pointers:

catalog id: whynot-design-npm-publish
mount: platform
path: platform/workloads/coulomb/whynot-design/npm-publish
field: NPM_AUTH_TOKEN
oidc login: bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
policy: workload-kv-read-whynot-design-npm-publish
policy file: openbao/policies/workload-kv-read-whynot-design-npm-publish.hcl
flex-auth ref: secret.read:whynot-design, if tenant policy requires it
runbook: docs/workload-kv-access-lanes.md

Until positive and negative caller verification are complete, ops-warden should keep the catalog entry in applied-pending-verify/non-active state with resolvable=false.

reuse-surface hub runtime secrets (CCR-2026-0005)

Production federation hub at https://reuse.coulomb.social. Runtime secrets are OpenBao-custodied and delivered to Railiance01 via External Secrets.

Item Value
CCR CCR-2026-0005-reuse-surface-runtime-secrets-lane
KV mount platform
OpenBao CLI path platform/workloads/reuse/reuse-surface/runtime-secrets
Fields REUSE_SURFACE_TOKEN, REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET
Read policy workload-kv-read-reuse-surface-runtime
Policy file openbao/policies/workload-kv-read-reuse-surface-runtime.hcl
K8s auth role external-secrets-reuse-surface (ESO delivery path)
Primary consumer ExternalSecret reuse/reuse-surface-runtime → Secret reuse-surface-env (Railiance01, 1h refresh)
Interim ClusterSecretStore openbao-reuse (token auth to https://bao.coulomb.social, namespace reuse)
ops-warden catalog reuse-surface-hub-write-token

Fetch hub write token (do not log the value):

export REUSE_SURFACE_TOKEN=$(
  bao kv get -field=REUSE_SURFACE_TOKEN \
    platform/workloads/reuse/reuse-surface/runtime-secrets
)

Webhook HMAC (dual consumer — Forgejo org webhook must match):

bao kv get -field=REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET \
  platform/workloads/reuse/reuse-surface/runtime-secrets

Or via ops-warden:

warden access reuse-surface-hub-write-token --fetch REUSE_SURFACE_TOKEN

Consumer facts the generated plan does not cover:

  • REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET is consumed by both the hub pod and the Forgejo org webhook. After rotation, run railiance-apps make reuse-forgejo-webhook once ESO has refreshed.
  • Break-glass cluster read remains available via kubectl ... get secret reuse-surface-env when OpenBao is down; steady-state custody is OpenBao + ESO only.
  • Rotation procedure: docs/reuse-surface-runtime-secrets-rotation-runbook.md; post-rotate smoke: make -C ~/railiance-apps reuse-webhook-smoke.

Railiance offsite backup lane (CCR-2026-0004)

Workstation and platform backup tools (railiance-backup, forgejo-backup) upload age-encrypted artifacts to the Nextcloud file drop (Option A, 2026-07-09).

Item Value
CCR CCR-2026-0004-railiance-backup-offsite-lane
KV mount platform
OpenBao CLI path platform/workloads/railiance/backup/offsite-lane
Fields NC_WEBDAV_TOKEN, NC_WEBDAV_URL, AGE_PRIVATE_KEY
Read policy workload-kv-read-railiance-backup-offsite-lane
Policy file openbao/policies/workload-kv-read-railiance-backup-offsite-lane.hcl
OIDC auth mount netkingdom
OIDC role railiance-backup-workload-kv-read
Bound claim groups=net-kingdom-admins (confirmed via live platform-admin role)
ops-warden catalog id railiance-backup-offsite-lane (draft until front door verified)

Caller login:

bao login -method=oidc -path=netkingdom role=railiance-backup-workload-kv-read

Fetch upload token for a backup run (do not log the value):

export RAILIANCE_BACKUP_NC_TOKEN=$(
  bao kv get -field=NC_WEBDAV_TOKEN platform/workloads/railiance/backup/offsite-lane
)
export RAILIANCE_BACKUP_NC_WEBDAV_URL=$(
  bao kv get -field=NC_WEBDAV_URL platform/workloads/railiance/backup/offsite-lane
)

Or let lib/railiance-backup-common.sh load from OpenBao after login when env is unset.

Recovery escrow (AGE_PRIVATE_KEY) is stored in the same path for disaster recovery; prefer the password-manager copy on restore drills per railiance-cluster/docs/backup-restore.md. Fetch only in attended sessions.

Forgejo admin API token lane (CCR-2026-0006)

Workstation and activity-core automation (forgejo-package-prune, org webhooks, operator bootstrap) need a Forgejo site-admin PAT. Phase 1 replaces the legacy workstation file /tmp/forgejo-tegwick-api-token and FORGEJO_ADMIN_TOKEN env drops with OpenBao custody. Sibling to forgejo-mailer (SMTP); no cluster ESO in phase 1.

Item Value
CCR CCR-2026-0006-forgejo-admin-api-token-lane
KV mount platform
OpenBao CLI path platform/workloads/forgejo/forgejo-admin
Fields API_TOKEN (secret); optional metadata API_USER, API_BASE_URL, TOKEN_SCOPES, GENERATED_AT
Read policy workload-kv-read-forgejo-admin
Policy file openbao/policies/workload-kv-read-forgejo-admin.hcl
OIDC auth mount netkingdom
OIDC role forgejo-admin-workload-kv-read
Bound claim groups=net-kingdom-admins
ops-warden catalog id forgejo-admin-api-token (draft until front door verified)

Caller login:

bao login -method=oidc -path=netkingdom role=forgejo-admin-workload-kv-read

Fetch PAT for a Forgejo API run (do not log the value):

export FORGEJO_ADMIN_TOKEN=$(
  bao kv get -field=API_TOKEN platform/workloads/forgejo/forgejo-admin
)

PAT mint: attended session as Forgejo user tegwick (site admin). Minimum scopes: read:package, write:package, read:repository, write:repository, plus admin scopes required by forgejo-operator-bootstrap. Downstream repos update load_token() to read OpenBao when env is unset after lane verification.

Tenant commercial secrets (mount tenants/) — WARDEN-WP-0028

Client/tenant secrets are not under platform/workloads/. They use a dedicated KV v2 mount:

tenants/<tenant_slug>/<workload>/<bundle>

CCR applier allowlist accepts mount: tenants and paths under tenants/ (in addition to platform/workloads/ for fleet lanes).

Binky company email IMAP (CCR-2026-0007)

Item Value
ops-warden catalog id binky-company-email-imap
Tenant binky
Mount tenants
OpenBao CLI path tenants/binky/company-email/imap
Fields IMAP_USERNAME, IMAP_PASSWORD
Read policy workload-kv-read-binky-company-email-imap
Policy file openbao/policies/workload-kv-read-binky-company-email-imap.hcl
OIDC role binky-company-email-imap-workload-kv-read
Front-door readiness draft / applied-pending-provision (values: founder Red)
Risk high
bao login -method=oidc -path=netkingdom role=binky-company-email-imap-workload-kv-read
# after provision:
bao kv get -field=IMAP_PASSWORD tenants/binky/company-email/imap   # interactive human only
warden access binky-company-email-imap --all --out /tmp/p          # preferred

Onboarding playbook: ops-warden/wiki/playbooks/tenant-secret-onboarding.md.