secrets-engine corrected our claim (msg 15f0c0ca): `npm_token` is the KV field on the whynot-design publish lane; `NPM_AUTH_TOKEN` is the environment variable their publication-scope policy injects. Their doc lists the two as separate rows and we had copied the env var in as the field name, so our `fetch_command` named a field that does not exist -- `bao kv get -field=NPM_AUTH_TOKEN` could only ever have failed. This is ADR-0001's failure mode, not a typo: a pointer layer restating an owner's procedure and getting it wrong. Corrected from the owner's statement rather than re-derived here, and the catalog now records the distinction inline so the env var does not get copied back in. The path is a separate and still-open question. secrets-engine declined to resolve it unilaterally -- which location backs the lane for reads is railiance-platform's custody state -- so the path is unchanged and routed to them rather than moved on a coordination message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013EPuTc18FjU5WFqoSEKH3C Assistant: claude-code Assistant-Model: opus Assistant-Process: 1276224@bnt-lap001 Assistant-Session: 426ec497-e1c4-4dd3-b417-dfce1ca1dbc3
5.1 KiB
whynot-design npm publish token
Date: 2026-09-04
Catalog: whynot-design-npm-publish (status active, resolvable: true)
Owner: railiance-platform (OpenBao) · provisioning CCR-2026-0001 (commit 8f617fc)
Rotation required (2026-09-04). The OIDC role and OpenBao read path are healthy, but the stored credential failed a real Forgejo publish. Version
@whynot/design@0.4.2was published and integrity-verified through the plan-authorized Forgejo admin recovery lane. Treat this dedicated lane as unverified for writes until its package token is rotated and re-proven.
The npm publish token for @whynot/design on the coulomb Forgejo npm registry
(KV field npm_token; reaching the publish command as NPM_AUTH_TOKEN)
(https://forgejo.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 |
| KV field | npm_token |
| Injected env var | NPM_AUTH_TOKEN (set by the publication-scope policy; not a KV key) |
| 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-publishpath from early in the provisioning thread is superseded — the live path is under thecoulombtenant.
Worker checklist
-
Authenticate as yourself (you need your own identity; ops-warden adds none):
bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-readYour token must carry the
whynot-designgroup bound claim; a non-whynot identity is denied by policy (verified negative case). -
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:
secrets-engine route whynot-design-npm-publish --json # pointer / readiness secrets-engine exec --catalog whynot-design-npm-publish -- \ npm view @whynot/design@<version> version \ --registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/ secrets-engine exec --catalog whynot-design-npm-publish -- npm publishops-warden transparent fallback — same lane via the
warden accessproxy (fetches as you, holds nothing). The project.npmrcmust point both the@whynotscope and token fragment atforgejo.coulomb.social:# --exec needs the env-var name. The zone-aware policy gate always runs first. warden access whynot-design-npm-publish --field npm_token \ --exec -- npm view @whynot/design@<version> version \ --registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/ warden access whynot-design-npm-publish --field npm_token \ --exec -- npm publish warden access whynot-design-npm-publish --field npm_token --fetchOn either path the value transits to you (or the child env) and never enters ops-warden's memory, disk, or audit log.
-
Readiness gate (for automated callers). Before attempting
--fetch, check the flag:warden route show whynot-design-npm-publish --json | jq .resolvable # trueresolvable: truemeans the lane is concrete and--fetchwill run; a template lane reportsfalse. -
Publish is outward-facing and immutable. Before publishing, confirm that
package.json#publishConfig.registryis exactly the Forgejo URL above, verify the intended version andnpm pack --dry-runcontents, and obtain explicit operator approval.npm publishis irreversible; do not auto-run it from an agent. -
Record non-secret release evidence. After the owner publishes, record only the package coordinate (for example
@whynot/design@0.4.2), registry URL, authenticated install result, and release-content verification. Never record the token or npm configuration generated for its delivery.Forgejo advertises
npm view, search, install, publish, unpublish, and dist-tag support; it does not advertisenpm whoami. Use the exact-version lookup above rather than treatingnpm whoamifailure as a credential failure.
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— thewarden accessfront door + guardrailswiki/CredentialRouting.md— routing modelrailiance-platform/docs/workload-kv-access-lanes.md,workplans/RAILIANCE-WP-0006-workload-kv-access-lanes.md