feat(routing): repoint whynot npm lane to Forgejo
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a06d83-1cbc-71f2-b0dc-e0f48cedae43
This commit is contained in:
parent
efabe526d8
commit
81f28ff814
4 changed files with 128 additions and 16 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
79
workplans/WARDEN-WP-0037-whynot-design-forgejo-npm-lane.md
Normal file
79
workplans/WARDEN-WP-0037-whynot-design-forgejo-npm-lane.md
Normal 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue