ops-warden/wiki/playbooks/whynot-design-npm-publish.md
tegwick 7ce58ae638
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
feat: adopt security zones and explicit workload refs
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1
2026-08-22 15:36:37 +02:00

85 lines
3.5 KiB
Markdown

# whynot-design npm publish token
Date: 2026-06-29
Catalog: `whynot-design-npm-publish` (status `active`, `resolvable: true`)
Owner: `railiance-platform` (OpenBao) · provisioning CCR-2026-0001 (commit 8f617fc)
The `NPM_AUTH_TOKEN` that publishes `@whynot/design` to the coulomb Gitea npm registry
(`https://gitea.coulomb.social/api/packages/coulomb/npm/`). ops-warden **does not hold
this token** — it is the access front door: `warden access` proxies the read from OpenBao
**as the caller** and never persists, caches, or logs the value.
---
## Owner-confirmed lane (no placeholders)
| Field | Value |
| --- | --- |
| OpenBao path | `platform/workloads/coulomb/whynot-design/npm-publish` |
| Field | `NPM_AUTH_TOKEN` |
| KV mount | `platform` |
| Read policy | `workload-kv-read-whynot-design-npm-publish` |
| OIDC login | `bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read` |
| Bound group | `whynot-design` |
| flex-auth ref | `secret.read:whynot-design` (if tenant policy requires pre-approval) |
| Runbook (owner) | `railiance-platform/docs/workload-kv-access-lanes.md` |
> The `platform/workloads/whynot-design/whynot-design/npm-publish` path from early in the
> provisioning thread is **superseded** — the live path is under the `coulomb` tenant.
---
## Worker checklist
1. **Authenticate as yourself** (you need your own identity; ops-warden adds none):
```bash
bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
```
Your token must carry the `whynot-design` group bound claim; a non-whynot identity is
denied by policy (verified negative case).
2. **Run via the owner-native front door (primary).** secrets-engine owns the secret-exec
for this lane (SECRETS-WP-0003, decision e6381a56); ops-warden routes to it:
```bash
secrets-engine route whynot-design-npm-publish --json # pointer / readiness
secrets-engine exec --catalog whynot-design-npm-publish -- npm publish
```
**ops-warden transparent fallback** — same lane via the `warden access` proxy (fetches as
you, holds nothing). Field-verified flags (whynot-design, @whynot/design@0.4.0):
```bash
# --exec needs the env-var name. The zone-aware policy gate always runs first.
warden access whynot-design-npm-publish --field NPM_AUTH_TOKEN \
--exec -- npm publish
warden access whynot-design-npm-publish --field NPM_AUTH_TOKEN --fetch
```
On either path the value transits to you (or the child env) and never enters
ops-warden's memory, disk, or audit log.
3. **Readiness gate (for automated callers).** Before attempting `--fetch`, check the flag:
```bash
warden route show whynot-design-npm-publish --json | jq .resolvable # true
```
`resolvable: true` means the lane is concrete and `--fetch` will run; a template lane
reports `false`.
4. **Publish is outward-facing and immutable.** `npm publish` is irreversible and public.
Even once the token resolves, hold for an explicit operator "yes, publish" — do not
auto-run it from an agent.
---
## Scopes
This lane is the **publish** token only. A separate **read/install** token (for consumers
of `@whynot/design`) is a distinct need and would be its own catalog id
(`whynot-design-npm-read`) once railiance-platform provisions it — do not conflate them.
---
## See also
- `wiki/OperatorAccessAssist.md` — the `warden access` front door + guardrails
- `wiki/CredentialRouting.md` — routing model
- `railiance-platform/docs/workload-kv-access-lanes.md`,
`workplans/RAILIANCE-WP-0006-workload-kv-access-lanes.md`