docs: seed SECRETS-WP-0004 (warden-sign lane); complete SCOPE.md sections
- SECRETS-WP-0004: scoped warden-sign OpenBao token lane for ops-warden, to unblock FLEX-WP-0007 T4 joint smoke. First auth-capability (non-KV) lane and first lane touching production OpenBao (bao.coulomb.social). - SCOPE.md: add the standard sections flagged by the repo scope review (Relevant When, Not Relevant When, How It Fits, Terminology, Related / Overlapping, Provided Capabilities with fenced capability blocks); refresh Current State to reflect the delivered MVP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9a65875bae
commit
bcdfc78087
2 changed files with 273 additions and 4 deletions
164
workplans/SECRETS-WP-0004-warden-sign-token-lane.md
Normal file
164
workplans/SECRETS-WP-0004-warden-sign-token-lane.md
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
---
|
||||
id: SECRETS-WP-0004
|
||||
type: workplan
|
||||
title: "Provision a scoped warden-sign token lane (ops-warden / FLEX-WP-0007 T4)"
|
||||
domain: infotech
|
||||
repo: secrets-engine
|
||||
status: proposed
|
||||
owner: codex
|
||||
topic_slug: custodian
|
||||
created: "2026-06-29"
|
||||
updated: "2026-06-29"
|
||||
---
|
||||
|
||||
# SECRETS-WP-0004 - Provision a scoped warden-sign token lane
|
||||
|
||||
## Goal
|
||||
|
||||
Give ops-warden a scoped OpenBao credential that can run `warden sign` over the
|
||||
HTTP API, minted and custodied by secrets-engine. Model it as a first-class
|
||||
secrets-engine **auth-capability lane** (an OpenBao policy + AppRole granting a
|
||||
narrow capability), not a KV value. Post the non-secret pointers to State Hub and
|
||||
hand the token/secret_id to the operator out-of-band.
|
||||
|
||||
This unblocks FLEX-WP-0007 T4 (the joint OpenBao + policy-gate production smoke),
|
||||
after which `policy.enabled: true` can go live on CoulombCore.
|
||||
|
||||
## Context
|
||||
|
||||
ops-warden raised this on State Hub (msg 077ac90d, 2026-06-28). warden's vault
|
||||
backend signs over the HTTP API (`X-Vault-Token`) and holds no standing OpenBao
|
||||
token (conduit-not-broker), so token custody/minting is squarely secrets-engine's
|
||||
lane. The operator cannot mint one interactively: the `bao` CLI is not installed
|
||||
on CoulombCore and `bao login -method=oidc` is therefore unavailable — hence the
|
||||
preference for an AppRole the operator can use non-interactively.
|
||||
|
||||
Target backend is the **production** OpenBao at `https://bao.coulomb.social`,
|
||||
mount `ssh`. Actors in scope: `agt-state-hub-bridge` (primary),
|
||||
`agt-codex-interhub-bootstrap`, `adm-example`, `atm-backup-daily`. The signing
|
||||
roles are `agt-role`, `adm-role`, `atm-role`.
|
||||
|
||||
This is the first non-KV, non-npm lane and the first lane that touches production
|
||||
OpenBao, so it also exercises parts of the engine the npm pilot did not.
|
||||
|
||||
## Design Constraints
|
||||
|
||||
- No token value or AppRole `secret_id` in Git, State Hub, chat, prompts,
|
||||
workplans, or normal logs — pointers only on the hub, value out-of-band.
|
||||
- The `warden-sign` policy must be narrow: `update` on `ssh/sign/<role>` for the
|
||||
allowlisted roles only. No broader `ssh/*`, no `sys/`, `auth/token/`,
|
||||
`identity/`, no root/sudo.
|
||||
- Production apply uses a mode-0600 bootstrap token outside any repo, revocable,
|
||||
recorded in `docs/hardening-backlog.md` H0.
|
||||
- ops-warden takes no custody; secrets-engine owns minting and revocation.
|
||||
|
||||
## Tasks
|
||||
|
||||
## T01 - Extend the catalog for auth-capability (non-KV) lanes
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0004-T01
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Add a lane kind that represents an OpenBao auth credential (AppRole + policy)
|
||||
granting a capability on a mount, rather than a KV value. The current schema
|
||||
assumes a KV `mount/path/fields` value and `provision --from-file`; an
|
||||
auth-capability lane has no stored value — the deliverable is the minted token /
|
||||
`secret_id`.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- The schema validates a `warden-sign` auth-capability lane (kind explicit).
|
||||
- KV-only assumptions (`kv_data_path`, from-file provisioning, value verification)
|
||||
are bypassed for this kind without weakening the npm KV path.
|
||||
- `plan`/`apply` produce a policy + AppRole for the lane.
|
||||
|
||||
## T02 - Define the warden-sign policy and AppRole
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0004-T02
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Author the `warden-sign` ACL policy and AppRole. Policy: `update` on
|
||||
`ssh/sign/agt-role` (plus `adm-role`, `atm-role`) on the `ssh` mount; nothing
|
||||
else. AppRole `warden-sign` bound to that policy with a short token TTL, usable
|
||||
non-interactively via `role_id` + `secret_id` (no `bao` CLI needed).
|
||||
|
||||
Acceptance:
|
||||
|
||||
- The policy lists exact allowed/denied paths; the guards in `roles.py` refuse any
|
||||
broader variant (`ssh/*`, `sys/`, `auth/token/`, `identity/`, wildcards, root).
|
||||
- Negative check: a token from this AppRole can `sign` only the allowlisted roles
|
||||
and is denied elsewhere on the `ssh` mount.
|
||||
- The AppRole issues a scoped token carrying only the sign capability.
|
||||
|
||||
## T03 - Apply against production OpenBao via bootstrap token
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0004-T03
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Apply the policy + AppRole on `https://bao.coulomb.social` using a mode-0600
|
||||
bootstrap token stored outside any repo. Idempotent re-apply.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- The `warden-sign` policy and AppRole exist on the production OpenBao.
|
||||
- The bootstrap token file is recorded in `docs/hardening-backlog.md` H0 with an
|
||||
explicit revocation task and TTL.
|
||||
- Apply evidence is non-secret (policy/role names, mount, addr, status — no value).
|
||||
|
||||
## T04 - Out-of-band handoff and non-secret pointers
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0004-T04
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Define and execute the handoff: mint a fresh `secret_id`, deliver it (with the
|
||||
`role_id`) to the operator out-of-band; warden does `approle login` to obtain a
|
||||
`VAULT_TOKEN`. Post the non-secret pointers on the ops-warden thread (policy name,
|
||||
AppRole name, mount `ssh`, addr `https://bao.coulomb.social`, token TTL, status).
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Pointers are posted to State Hub; no token value or `secret_id` appears there or
|
||||
in Git/logs.
|
||||
- The operator can run, on CoulombCore:
|
||||
`FLEX_AUTH_EXTERNAL=1 SMOKE_VAULT=1 VAULT_TOKEN=<scoped> ~/ops-warden/scripts/policy_gate_production_smoke.sh`.
|
||||
|
||||
## T05 - Confirm the joint smoke and signal ops-warden
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0004-T05
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Confirm the unblock end to end, then reply to ops-warden (msg 077ac90d) with the
|
||||
pointers and runbook alignment. The reply is the explicit "we will signal
|
||||
ops-warden when done" step.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Allow path resolves to `backend: vault` + a `policy_decision_id`; deny path
|
||||
(ttl 999) is rejected by flex-auth before OpenBao.
|
||||
- ops-warden is replied to on State Hub with the non-secret pointers.
|
||||
- A revocation/rotation task exists for the minted credential.
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- A narrow `warden-sign` policy + AppRole exist on production OpenBao, minted and
|
||||
custodied by secrets-engine, granting only `ssh/sign/<allowlisted-role>` update.
|
||||
- The operator can obtain a scoped `VAULT_TOKEN` non-interactively without `bao`.
|
||||
- FLEX-WP-0007 T4 joint smoke is unblocked (or blocked only on an explicit
|
||||
external condition).
|
||||
- ops-warden has the non-secret pointers; no secret value crossed State Hub.
|
||||
- The bootstrap token and the minted credential have revocation tasks.
|
||||
Loading…
Add table
Add a link
Reference in a new issue