diff --git a/workplans/WARDEN-WP-0014-operator-access-assist.md b/workplans/WARDEN-WP-0014-operator-access-assist.md new file mode 100644 index 0000000..57232a8 --- /dev/null +++ b/workplans/WARDEN-WP-0014-operator-access-assist.md @@ -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 [--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 --fetch` — policy-gate (G3) → `exec` the owning tool + (`bao kv get ...`) **as the caller** → stream value to stdout. No buffering, no log. +- [ ] `warden access --exec -- ` — 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 G1–G3 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 G1–G3; 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 ` 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`