Add WARDEN-WP-0014 operator access assist workplan

Extends the routing charter from a pointer-layer to an assist-layer:
a `warden access` front door that advises for any credential need and
proxies the OpenBao/key-cape lanes as a transparent, policy-gated,
audited conduit — never holding or persisting secret values.

Registered in State Hub (workstream 3c30b2ed); T1 in progress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-27 15:58:09 +02:00
parent a187370030
commit 18b2a42463

View File

@@ -0,0 +1,192 @@
---
id: WARDEN-WP-0014
type: workplan
title: "Operator Access Assist — warden access front door"
domain: infotech
repo: ops-warden
status: active
owner: codex
topic_slug: custodian
planning_priority: high
planning_order: 14
created: "2026-06-27"
updated: "2026-06-27"
state_hub_workstream_id: "3c30b2ed-6ede-4b95-a438-fde6da6f6633"
---
# WARDEN-WP-0014 — Operator Access Assist (`warden access`)
**Scope:** Make ops-warden the consistent operator-facing front door for **every**
NetKingdom security/access need — not just the SSH lane. Add a `warden access`
command surface that (a) advises: emits the auth method, path, policy context, and
exact command skeleton for any credential need, and (b) **proxies**: transparently
fetches the value from the owning subsystem *as the caller* and streams it to the
operator's destination, **without ops-warden ever persisting, caching, or logging
the secret, and without ops-warden holding any standing privileged credential.**
Centralize **knowledge and policy** in ops-warden; leave **custody and execution
detail** in the owning subsystems (OpenBao, key-cape, flex-auth). ops-warden becomes
a transparent, policy-gated, audited conduit — `vault exec` / `op run` shaped — never
a standing secret broker.
**Charter note:** This extends the WP-0010 routing charter from a *pointer layer*
("who owns it") to an *assist layer* ("here is exactly how to get it, gated and
audited"). It does **not** move custody into ops-warden. See the three non-negotiable
guardrails below — they are the line between a transparent conduit (sanctioned) and a
standing broker/honeypot (forbidden).
**Out of scope:**
- ops-warden holding a long-lived OpenBao/secret-read token of its own.
- Persisting, caching, or logging any secret **value** anywhere (disk, log, hub, git).
- Creating OpenBao paths or policies (coordinate with railiance-platform / flex-auth).
- Restating an owner's procedure as prose in the catalog (reference canon, don't copy).
- Identity/MFA implementation (key-cape owns it; we orchestrate its CLI only).
**Depends on:** WP-0010 (charter + catalog schema), WP-0011 (`warden route` CLI),
WP-0007/0009 (flex-auth policy gate — reused as the fetch-path gate).
**Status:** `proposed` — awaiting Bernd's review before implementation.
---
## Three non-negotiable guardrails (acceptance-blocking)
These are the design invariants that keep proxy mode safe. Any task that violates one
is rejected regardless of convenience.
1. **Operator identity, never warden's.** `--fetch`/`--exec` authenticate as the
*caller* (their OIDC/OpenBao token, the agent's own auth). ops-warden carries **no**
standing secret-read credential. If the caller has no valid auth, the command fails
with a routing pointer to the auth step — it does not fall back to a warden token.
2. **Transit only — no persistence, no logging of values.** The secret flows
subsystem → caller destination (env of a child process, or stdout) via a streamed
`exec`. ops-warden must not buffer it to disk, cache it, echo it to logs, or write
it to the State Hub. Audit records **metadata only** (who, need id, owner path, time,
policy decision id) — never the value.
3. **Policy gate on the fetch path.** `--fetch`/`--exec` run the flex-auth check
**before** proxying (reusing the WP-0007 gate). When `policy.enabled: false`, fetch
is **advisory-only** by default and requires an explicit `--no-policy` acknowledgement
to proxy ungated — surfaced loudly in output and audit.
---
## Phasing decision (default — adjust in review)
OpenBao lane **first** (covers the immediate npm/API/DB need), key-cape/login lane in
a later task within the same WP. Rationale: OpenBao KV is the highest-frequency operator
need and the one this conversation surfaced; login flows are a thinner orchestration of
an interactive tool and lower risk to defer.
---
## Tasks
### T1 — Catalog schema: structured handoff fields
```task
id: WARDEN-WP-0014-T01
status: progress
priority: high
state_hub_task_id: "abb0e722-6524-4224-8638-6ee1573ed3e0"
```
- [ ] Extend `registry/routing/catalog.yaml` entry schema with optional structured
handoff fields for non-SSH lanes: `auth_method`, `path_template`,
`fetch_command`, `exec_capable` (bool), `policy_ref`.
- [ ] Fields are **generated/structured pointers**, not prose restatements — each links
to the owner's canon (`canon_ref`) for the authoritative procedure (no drift).
- [ ] Populate for `openbao-api-key` (and the coulomb_social npm shape from this thread)
as the reference example; leave `draft` entries `draft`.
- [ ] Validation: schema check rejects a `fetch_command` that embeds a literal value.
### T2 — `warden access` advisory surface
```task
id: WARDEN-WP-0014-T02
status: todo
priority: high
state_hub_task_id: "c1497263-7124-459f-b63a-d0c0c7005c86"
```
- [ ] `warden access <need> [--domain X] [--json]` — resolves via the same matcher as
`warden route find`, but renders the **structured handoff**: owner, auth method,
path template, command skeleton, policy ref + gate status, and any "unconfirmed
path → provision request" note.
- [ ] Advisory is the **default** behavior (no value fetched).
- [ ] `--json` output for agentic operators (stable shape, documented).
### T3 — OpenBao proxy lane (`--fetch` / `--exec`)
```task
id: WARDEN-WP-0014-T03
status: todo
priority: high
state_hub_task_id: "6d3eb0e4-309c-4065-893e-6c4053fb0db2"
```
- [ ] `warden access <need> --fetch` — policy-gate (G3) → `exec` the owning tool
(`bao kv get ...`) **as the caller** → stream value to stdout. No buffering, no log.
- [ ] `warden access <need> --exec -- <cmd>` — run a child command with the secret
injected into *its* env only (à la `op run`); value never lands in the caller's
shell history or persistent env.
- [ ] Enforce guardrails G1G3 in code; unit + integration tests assert: no value on
disk, no value in logs, no standing warden credential, gate runs before fetch.
- [ ] Audit event (metadata only) written per fetch — reuse the signatures-log pattern.
### T4 — key-cape / login orchestration lane
```task
id: WARDEN-WP-0014-T04
status: todo
priority: medium
state_hub_task_id: "481997e4-193d-4724-84a6-61cbc2940153"
```
- [ ] Extend `warden access` to orchestrate the key-cape/Keycloak OIDC login flow
(interactive tool hand-off) under the same advisory/proxy split.
- [ ] Login lane respects G1G3; no token caching by warden.
### T5 — Docs, security model, and INTENT/SCOPE alignment
```task
id: WARDEN-WP-0014-T05
status: todo
priority: medium
state_hub_task_id: "a5eb616e-4edf-42db-a4fb-bf296cdb92bc"
```
- [ ] `wiki/OperatorAccessAssist.md` — the `warden access` contract, the conduit-vs-broker
boundary, and the three guardrails as a security model statement.
- [ ] Update `wiki/AccessRouting.md` (issue/route/**assist** roles), `CredentialRouting.md`,
and the `credential-routing.md` agent rule (new anti-pattern: "warden as standing
broker" is forbidden; transparent `--fetch` is sanctioned).
- [ ] SCOPE/INTENT: record the charter extension from pointer-layer to assist-layer and
bump the maturity vector (A4 → A5 candidate on Availability).
- [ ] `history/2026-06-27-operator-access-assist-charter.md` — decision record for the
proxy-mode choice and its guardrails.
---
## Acceptance
- `warden access <need>` advises for any catalog need; `--fetch`/`--exec` proxy the
OpenBao lane end to end against a real KV path.
- All three guardrails hold under test: **no** secret value touches disk/log/hub/git;
ops-warden holds **no** standing secret-read credential; the policy gate runs **before**
every fetch.
- Catalog carries structured handoff fields that reference (never restate) owner canon.
- Docs state the conduit-vs-broker boundary explicitly; the agent rule forbids the
broker pattern.
- No secret material anywhere in code, catalog, docs, logs, or tests.
---
## See also
- `WARDEN-WP-0010` (routing charter), `WARDEN-WP-0011` (`warden route` CLI)
- `WARDEN-WP-0007` / `WARDEN-WP-0009` (flex-auth policy gate — reused as fetch gate)
- `wiki/AccessRouting.md`, `wiki/CredentialRouting.md`, `wiki/PolicyGatedSigning.md`
- `.claude/rules/credential-routing.md`
- `history/2026-06-24-intent-scope-gap-analysis.md`