CUST-WP-0075: catalog entry core-hub-forgejo-source-read (CCR-2026-0031)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 3775@bnt-lap001 Assistant-Session: cfacb6a5-ad5b-4f79-ac67-053e3b0d34a3
This commit is contained in:
parent
88c22d43c9
commit
2f8387cc2f
5 changed files with 121 additions and 3 deletions
|
|
@ -94,14 +94,14 @@ on_apply:
|
|||
# a register that cannot detect its own staleness is only as good as the last
|
||||
# re-measure, and this one was stale by eight lanes before the test caught it.
|
||||
classification_coverage:
|
||||
measured: "2026-09-28"
|
||||
measured: "2026-10-03"
|
||||
attribution: self-measured
|
||||
signing_targets:
|
||||
resolved: 0
|
||||
unknown: 3
|
||||
not_applicable: 1
|
||||
routing_lanes:
|
||||
resolved: 3
|
||||
resolved: 4
|
||||
unknown: 20
|
||||
not_applicable: 15
|
||||
|
||||
|
|
|
|||
|
|
@ -390,6 +390,45 @@ entries:
|
|||
- "Use the attended railiance-platform bootstrap to update OpenBao and the coulomb/policy-nexus FORGEJO_SOURCE_TOKEN Actions secret without exposing the value."
|
||||
- "Pass one exact-commit candidate workflow, then revoke the predecessor PAT and record bounded non-secret evidence in CCR-2026-0014."
|
||||
|
||||
- id: core-hub-forgejo-source-read
|
||||
title: Core Hub repo-manager publisher Forgejo private-source repository read token
|
||||
# Read-only at Forgejo, but disclosure grants estate-wide private source read for
|
||||
# org coulomb. ESO is the only consumer (CCR-2026-0031): no operator fetch lane,
|
||||
# so exec_capable stays false and Warden never proxies a read of this value.
|
||||
risk: high
|
||||
workload_ref:
|
||||
applicability: applicable
|
||||
rapp_id: rapp-core-hub
|
||||
name: core-hub
|
||||
deployable: repository-classification-publisher
|
||||
fields: [FORGEJO_SOURCE_TOKEN, API_USER, API_BASE_URL, TOKEN_SCOPES, GENERATED_AT] # CCR-2026-0031
|
||||
need_keywords: [core-hub, core, hub, repo-manager, publisher, forgejo, private, source, repository, read, token, eso, external-secrets, FORGEJO_SOURCE_TOKEN]
|
||||
owner_repo: railiance-platform
|
||||
subsystem: OpenBao + External Secrets + Forgejo
|
||||
warden_executes: false
|
||||
wiki_ref: wiki/playbooks/core-hub-forgejo-source-read.md#worker-checklist
|
||||
canon_ref: railiance-platform/credential-change-requests/CCR-2026-0031-core-hub-forgejo-source-read.yaml
|
||||
reviewed: "2026-10-03"
|
||||
status: active
|
||||
delegation:
|
||||
mode: native
|
||||
intended_owner: railiance-platform
|
||||
reviewed: "2026-10-03"
|
||||
verified: source-read
|
||||
auth_method: "Kubernetes auth (mount kubernetes) role=external-secrets-core-hub-forgejo-source, bound to external-secrets/external-secrets; ESO delivery only (ClusterSecretStore openbao-core-hub-forgejo-source → ExternalSecret core-hub/repo-manager-forgejo-source)"
|
||||
path_template: "platform/workloads/core-hub/forgejo-source-read"
|
||||
policy_ref: "workload-kv-read-core-hub-forgejo-source"
|
||||
exec_capable: false
|
||||
lane: secret
|
||||
rotation:
|
||||
method: rotate
|
||||
owner: railiance-platform
|
||||
automatable: false
|
||||
steps:
|
||||
- "Every 180 days or on owner change: mint a replacement PAT for the restricted core-hub-source identity with scope exactly read:repository; retain the predecessor until verification passes."
|
||||
- "Write the replacement to platform/workloads/core-hub/forgejo-source-read from stdin through the attended railiance-platform bootstrap, then let ESO refresh core-hub/repo-manager-forgejo-source (5m)."
|
||||
- "Pass make verify-publisher in rapp-core-hub, then revoke the predecessor PAT and record bounded non-secret evidence in CCR-2026-0031."
|
||||
|
||||
- id: flex-auth-policy-check
|
||||
title: Authorization decision — may this actor perform this action
|
||||
# Returns an authorization decision; no credential flows (WARDEN-WP-0032-T05).
|
||||
|
|
|
|||
|
|
@ -197,6 +197,32 @@ def test_route_find_policy_nexus_source_read_prefers_concrete_lane():
|
|||
assert matches[0].id == "policy-nexus-forgejo-source-read"
|
||||
|
||||
|
||||
def test_core_hub_source_read_lane_is_eso_only_and_not_resolvable():
|
||||
"""CCR-2026-0031: ESO is the only consumer, so no operator fetch lane."""
|
||||
catalog = load_catalog(_repo_catalog())
|
||||
entry = catalog.get("core-hub-forgejo-source-read")
|
||||
assert entry is not None and entry.is_active
|
||||
assert entry.exec_capable is False
|
||||
assert entry.resolvable is False
|
||||
assert entry.fetch_command is None
|
||||
assert entry.lane == "secret"
|
||||
assert entry.risk == "high"
|
||||
assert entry.owner_repo == "railiance-platform"
|
||||
assert entry.path_template == "platform/workloads/core-hub/forgejo-source-read"
|
||||
assert "role=external-secrets-core-hub-forgejo-source" in entry.auth_method
|
||||
assert entry.delegation is not None and entry.delegation.mode == "native"
|
||||
assert entry.canon_ref.endswith("CCR-2026-0031-core-hub-forgejo-source-read.yaml")
|
||||
|
||||
|
||||
def test_route_find_core_hub_source_read_prefers_core_hub_lane():
|
||||
catalog = load_catalog(_repo_catalog())
|
||||
matches = catalog.find(
|
||||
"core hub repo-manager publisher Forgejo private source repository read token",
|
||||
limit=1,
|
||||
)
|
||||
assert matches[0].id == "core-hub-forgejo-source-read"
|
||||
|
||||
|
||||
def test_generic_and_template_lanes_not_resolvable():
|
||||
catalog = load_catalog(_repo_catalog())
|
||||
# generic openbao lane has <FIELD>/<path_template>; login lane has <domain>.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ ROOT = Path(__file__).resolve().parents[1]
|
|||
def test_repo_catalog_uses_only_explicit_workload_references():
|
||||
report = build(ROOT / "registry/routing/catalog.yaml", Path.home())
|
||||
assert report["ok"] is True
|
||||
assert len(report["resolved"]) == 3
|
||||
assert len(report["resolved"]) == 4
|
||||
assert len(report["unknown"]) == 20
|
||||
# 15 since 2026-09-21: the layer-declaration route is repository conformance
|
||||
# guidance, not a workload delivery lane, and the two NetKingdom SSO lanes
|
||||
|
|
@ -25,6 +25,7 @@ def test_repo_catalog_uses_only_explicit_workload_references():
|
|||
"ops-warden-warden-sign-token",
|
||||
"issue-core-ingestion-api-key",
|
||||
"rapp-qonto-keycape-client",
|
||||
"core-hub-forgejo-source-read", # CCR-2026-0031, 2026-10-03
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
52
wiki/playbooks/core-hub-forgejo-source-read.md
Normal file
52
wiki/playbooks/core-hub-forgejo-source-read.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Core Hub Forgejo source-read token
|
||||
|
||||
Date: 2026-10-03
|
||||
Catalog: `core-hub-forgejo-source-read` (status `active`, `exec_capable: false`, `resolvable: false`)
|
||||
Owner: `railiance-platform` (OpenBao and credential lifecycle)
|
||||
|
||||
This lane carries the dedicated Forgejo PAT that the Core Hub repo-manager
|
||||
publisher (`rapp-core-hub`, deployable `repository-classification-publisher`)
|
||||
uses to read private sources of the repository registry. The Forgejo identity
|
||||
`core-hub-source` is restricted to organization-wide repository-code read in org
|
||||
`coulomb`, and the PAT scope is exactly `read:repository`. It has no repository
|
||||
write, package, organization administration, instance administration, Actions,
|
||||
cluster, or deployment authority.
|
||||
|
||||
The authoritative lifecycle and evidence record is
|
||||
`railiance-platform/credential-change-requests/CCR-2026-0031-core-hub-forgejo-source-read.yaml`
|
||||
(design: `railiance-platform/docs/credential-lane-designs/core-hub-forgejo-source-read.md`).
|
||||
It is distinct from `policy-nexus-forgejo-source-read` (CCR-2026-0014); neither
|
||||
identity nor token is reused across the two lanes.
|
||||
|
||||
## Owner-confirmed lane
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| OpenBao path | `platform/workloads/core-hub/forgejo-source-read` |
|
||||
| Fields | `FORGEJO_SOURCE_TOKEN`, `API_USER`, `API_BASE_URL`, `TOKEN_SCOPES`, `GENERATED_AT` |
|
||||
| Read policy | `workload-kv-read-core-hub-forgejo-source` |
|
||||
| Auth | Kubernetes auth role `external-secrets-core-hub-forgejo-source` (bound to `external-secrets/external-secrets`) |
|
||||
| Delivery | ClusterSecretStore `openbao-core-hub-forgejo-source` → ExternalSecret `core-hub/repo-manager-forgejo-source` → Secret key `token` |
|
||||
| Forgejo identity | `core-hub-source` |
|
||||
| Forgejo team | `core-hub-source-readers` |
|
||||
|
||||
## Worker checklist
|
||||
|
||||
1. There is no operator or agent fetch lane. External Secrets is the only reader,
|
||||
so `warden access core-hub-forgejo-source-read --fetch/--exec` is not offered
|
||||
and the fetch-policy pin does not list this lane. Do not request one; if a
|
||||
legitimate operator read need appears, it goes through a new CCR first.
|
||||
|
||||
2. Check delivery health without reading values: ExternalSecret
|
||||
`core-hub/repo-manager-forgejo-source` Ready, and `make verify-publisher` in
|
||||
`rapp-core-hub`. Verify OpenBao allow/deny with `bao token capabilities`, never
|
||||
`bao kv get` (see `catalog-lane-promotion.md`).
|
||||
|
||||
3. For rotation (every 180 days or on owner change), deactivation, or compromise,
|
||||
follow the CCR-2026-0031 lifecycle; `warden rotate-guide core-hub-forgejo-source-read`
|
||||
prints the rotation steps. A replacement is not active until `make
|
||||
verify-publisher` passes; revoke the predecessor afterward.
|
||||
|
||||
4. Never place the value in argv, chat, Git, State Hub, logs, or a persistent
|
||||
temporary file. Never substitute the Forgejo admin PAT, a personal token, or
|
||||
the policy-nexus-source token.
|
||||
Loading…
Add table
Add a link
Reference in a new issue