feat(routing): repoint whynot npm lane to Forgejo
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06d83-1cbc-71f2-b0dc-e0f48cedae43
This commit is contained in:
tegwick 2026-09-04 23:39:11 +02:00
parent efabe526d8
commit 81f28ff814
4 changed files with 128 additions and 16 deletions

View file

@ -196,19 +196,19 @@ entries:
lane: ceremony
- id: whynot-design-npm-publish
title: whynot-design npm publish token (@whynot/design → coulomb Gitea registry)
title: whynot-design npm publish token (@whynot/design → coulomb Forgejo registry)
# Publish rights to the package registry — a leaked token is a supply-chain write, not a read (WARDEN-WP-0032-T05).
risk: high
workload_ref:
applicability: applicable
unknown_reason: "whynot-design has not published an authoritative workload identity declaration."
need_keywords: [whynot-design, whynot, npm, publish, npm_auth_token, gitea, registry, coulomb, package]
need_keywords: [whynot-design, whynot, npm, publish, npm_auth_token, forgejo, registry, coulomb, package]
owner_repo: railiance-platform
subsystem: OpenBao
warden_executes: false
wiki_ref: wiki/playbooks/whynot-design-npm-publish.md#worker-checklist
canon_ref: net-kingdom/docs/platform-identity-security-architecture.md
reviewed: "2026-06-29"
reviewed: "2026-09-04"
status: active
delegation:
mode: native
@ -238,9 +238,9 @@ entries:
owner: railiance-platform
automatable: false
steps:
- "In the coulomb Gitea/Forgejo registry, revoke the current @whynot/design publish token and generate a new one (scope: package read/write) for the whynot-design publish identity."
- "In the coulomb Forgejo registry, revoke the current @whynot/design publish token and generate a new one (scope: package read/write) for the whynot-design publish identity."
- "Write it back: `bao kv put platform/workloads/coulomb/whynot-design/npm-publish NPM_AUTH_TOKEN=@file` (value from a mode-0600 file)."
- "Verify capabilities-safe, then confirm publish works via `secrets-engine exec --catalog whynot-design-npm-publish -- npm whoami` (value used, not printed)."
- "Verify capabilities-safe, then publish a fresh version and confirm it with Forgejo-supported `npm view <package>@<version>` through the governed execution lane (value used, not printed)."
- id: policy-nexus-forgejo-source-read
title: Policy Nexus Forgejo private-source repository read token
@ -325,8 +325,8 @@ entries:
# point is to obtain one). warden runs it interactively as the caller and never
# captures the resulting token — the owner tool writes it to the caller's store.
lane: login
auth_method: "browser OIDC via key-cape / Keycloak"
fetch_command: "bao login -method=oidc role=<domain>"
auth_method: "browser OIDC via key-cape / Keycloak at auth/netkingdom"
fetch_command: "bao login -no-print -method=oidc -path=netkingdom role=<domain>"
exec_capable: true
- id: ops-bridge-tunnel

View file

@ -144,13 +144,19 @@ def test_route_find_vault_token_ops_warden_prefers_broker_lane():
def test_whynot_design_npm_lane_is_concrete_and_resolvable():
"""The provisioned npm publish lane has no placeholders and reports resolvable."""
"""The provisioned Forgejo npm lane is exact, concrete, and resolvable."""
catalog = load_catalog(_repo_catalog())
e = catalog.get("whynot-design-npm-publish")
assert e is not None and e.is_active and e.exec_capable
assert e.resolvable is True
assert "Forgejo registry" in e.title
assert "forgejo" in e.need_keywords
assert "gitea" not in e.need_keywords
assert "<" not in e.fetch_command and ">" not in e.fetch_command
assert "platform/workloads/coulomb/whynot-design/npm-publish" in e.fetch_command
rotation = " ".join(e.rotation.steps)
assert "Forgejo-supported `npm view <package>@<version>`" in rotation
assert "Gitea" not in rotation
def test_policy_nexus_source_read_lane_is_exact_high_risk_and_resolvable():
@ -183,7 +189,11 @@ def test_generic_and_template_lanes_not_resolvable():
catalog = load_catalog(_repo_catalog())
# generic openbao lane has <FIELD>/<path_template>; login lane has <domain>.
assert catalog.get("openbao-api-key").resolvable is False
assert catalog.get("key-cape-oidc-login").resolvable is False
login = catalog.get("key-cape-oidc-login")
assert login.resolvable is False
assert login.fetch_command == (
"bao login -no-print -method=oidc -path=netkingdom role=<domain>"
)
def test_platform_admin_login_lane_is_exact_and_non_value_bearing():

View file

@ -1,11 +1,17 @@
# whynot-design npm publish token
Date: 2026-06-29
Date: 2026-09-04
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
> **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.2` was 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_AUTH_TOKEN` that publishes `@whynot/design` to the coulomb Forgejo npm registry
(`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.
@ -42,13 +48,20 @@ this token** — it is the access front door: `warden access` proxies the read f
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 view @whynot/design@<version> version \
--registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
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):
you, holds nothing). The project `.npmrc` must point both the `@whynot` scope and
token fragment at `forgejo.coulomb.social`:
```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 view @whynot/design@<version> version \
--registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
warden access whynot-design-npm-publish --field NPM_AUTH_TOKEN \
--exec -- npm publish
warden access whynot-design-npm-publish --field NPM_AUTH_TOKEN --fetch
@ -63,9 +76,19 @@ this token** — it is the access front door: `warden access` proxies the read f
`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.
4. **Publish is outward-facing and immutable.** Before publishing, confirm that
`package.json#publishConfig.registry` is exactly the Forgejo URL above, verify the
intended version and `npm pack --dry-run` contents, and obtain explicit operator
approval. `npm publish` is irreversible; do not auto-run it from an agent.
5. **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 advertise `npm whoami`. Use the exact-version lookup above
rather than treating `npm whoami` failure as a credential failure.
---

View file

@ -0,0 +1,79 @@
---
id: WARDEN-WP-0037
type: workplan
title: "Repoint the whynot-design npm lane to Forgejo"
domain: infotech
repo: ops-warden
status: active
owner: codex
topic_slug: whynot-design-forgejo-npm-lane
created: "2026-09-04"
updated: "2026-09-04"
state_hub_workstream_id: "42a097db-1c24-558e-a724-030bb2b4443e"
---
## Verify the existing credential against Forgejo
```task
id: WARDEN-WP-0037-T01
status: done
priority: high
state_hub_task_id: "afc4d325-1c6d-5c25-aaf7-2118aa8f86c6"
```
Use only the governed execution transport to test the existing publish identity
against the canonical Forgejo npm endpoint. Do not print or persist the token.
2026-09-04: `warden plan` classified the exact verification as autonomous and
selected this lane. A contained login using the documented
`whynot-design-workload-kv-read` role proved `read` on the exact OpenBao data
path, and the governed child proved the secret is present. A real 0.4.2 publish
through that credential then failed. No value was printed or persisted and each
contained session self-revoked. The lane therefore needs token rotation, not an
OpenBao policy repair.
## Repoint the catalog and playbook
```task
id: WARDEN-WP-0037-T02
status: done
priority: high
state_hub_task_id: "7ceb2f74-496c-54e8-bf5a-3c49f994ff23"
```
Replace the retired Gitea endpoint and discovery language with Forgejo while
preserving the established OpenBao path, field, and least-privilege boundary.
This delivers the npm facet of routed intake
`01a06e07-f2f9-7586-9745-b359eb0025b6`; its inter-hub SSH facet remains separate.
Completed 2026-09-04. The catalog title, discovery keywords, rotation guidance,
and worker playbook now name the canonical Forgejo registry at
`https://forgejo.coulomb.social/api/packages/coulomb/npm/`. The OpenBao path,
field, owner, native-exec pointer, and high-risk boundary are unchanged. A
regression assertion prevents the retired Gitea discovery term and guidance
from returning.
## Prove routing and publication
```task
id: WARDEN-WP-0037-T03
status: wait
priority: high
state_hub_task_id: "a8b1b855-ab34-5835-b9fd-5f48bc0b6817"
```
Pass catalog and routing tests, verify the checkout route, and record the exact
Forgejo package release proven through the lane.
2026-09-04: repo-local verification is complete: the checkout route ranks
`whynot-design-npm-publish` first for a Forgejo npm publish need, reports the
canonical Forgejo title and verification command, all focused
routing/access/proxy tests pass (`145 passed`).
The sibling repo's `@whynot/design@0.4.2` release (105 files; IR
`designVersion` 0.4.2; five visual tests pass) was published through the
plan-authorized `forgejo-admin-api-token` one-time recovery lane. An
authenticated exact-version lookup proved that Forgejo's remote integrity
matches the local dry-run. T03 waits only on rotating the dedicated package
token and proving the next fresh version through `whynot-design-npm-publish`;
the package migration itself is complete.