--- id: WARDEN-WP-0019 type: workplan title: "Route secret-exec lanes to secrets-engine (route-primary, proxy fallback)" domain: infotech repo: ops-warden status: finished owner: claude topic_slug: custodian planning_priority: high planning_order: 19 created: "2026-06-29" updated: "2026-06-29" state_hub_workstream_id: "5e49abb6-497f-4640-a484-2da5f39a7c4e" --- # WARDEN-WP-0019 — Route secret-exec lanes to secrets-engine **Trigger:** secrets-engine (SECRETS-WP-0003, msg 765a03f0) shipped a native secret-exec front door — `secrets-engine route --json` and `secrets-engine exec --catalog -- ` with canonical decision ids — and asked ops-warden to **route to it**. This is the owner-native execution lane that ops-warden's `warden access --exec` proxy was filling as a stopgap (WP-0014). whynot-design already published `@whynot/design@0.4.0` through the proxy on this same lane, so both paths resolve today. **Decision (Bernd, 2026-06-29): route-primary, proxy-fallback.** For lanes secrets-engine owns, ops-warden surfaces `secrets-engine exec/route` as the **primary** path and keeps its own `warden access --exec` as a documented **transparent fallback**. ops-warden stays the discovery front door; secrets-engine is the exec owner. Boundary unchanged: ops-warden holds or stores no token on either path. **Out of scope:** ops-warden invoking `secrets-engine exec` itself (it routes/points, the caller runs it); changing the proxy's security model; the production policy-gate flip. --- ## Tasks ### T1 — Catalog + CLI: surface the owner-native exec front door ```task id: WARDEN-WP-0019-T01 status: done priority: high state_hub_task_id: "ea153605-7a14-4db7-8bce-d780ea143f8a" ``` - [x] `RouteEntry` gains `exec_owner` / `exec_command` / `pointer_command` (pointers only, screened by `_assert_no_secret_material`) and a `has_native_exec` property. - [x] `whynot-design-npm-publish` entry: `exec_owner: secrets-engine`, `exec_command: secrets-engine exec --catalog whynot-design-npm-publish -- `, `pointer_command: secrets-engine route whynot-design-npm-publish --json`. Keep the existing `fetch_command`/`exec_capable` (the proxy fallback). - [x] `warden access`: when `exec_owner` is set, render the secrets-engine exec as the **primary** line and the `warden access --exec` proxy as the **fallback**; JSON gains `exec_owner`/`exec_command`/`pointer_command`. `route find/show` JSON too. - [x] Tests in `tests/test_routing.py` / `tests/test_access.py`. ### T2 — Agent rule, SCOPE, playbook ```task id: WARDEN-WP-0019-T02 status: done priority: medium state_hub_task_id: "96059b8a-8938-4763-b3d0-cc5a0eb2465c" ``` - [x] `.claude/rules/credential-routing.md`: add secrets-engine as the secret-exec owner; for OpenBao-backed secret lanes the route is "secrets-engine `exec` (primary), ops-warden `warden access --exec` (transparent fallback)". - [x] SCOPE: add secrets-engine to Related Repos + the routing model; note the whynot-design lane is **production-exercised** (real 0.4.0 publish), not just resolvable. - [x] `wiki/playbooks/whynot-design-npm-publish.md`: lead with the secrets-engine exec command; fix the fallback one-liner per whynot-design's field notes (`--field NPM_AUTH_TOKEN`, and `--no-policy` while `policy.enabled=false`). --- ## Acceptance - `warden access whynot-design-npm-publish` shows the secrets-engine exec as primary and the warden proxy as fallback; `--json` carries `exec_owner`/`exec_command`. - The credential-routing rule names secrets-engine as the secret-exec owner. - No secret material anywhere; ops-warden holds no token on either path. ## See also - secrets-engine SECRETS-WP-0003, decision e6381a56, `docs/whynot-design-real-publish-closeout.md` - `WARDEN-WP-0014` (proxy), `WARDEN-WP-0017` (discoverability), `WARDEN-WP-0018` (lane activation)