Minted on a dedicated identity rather than a site admin. A PAT on tegwick would have read every repository on the instance — wider than the approved organisation-wide breadth and wider than the plan's stated blast radius. Built as user state-hub-svc in team coulomb/state-hub-read (read, all repositories, repo.code unit only), following the existing issue-core-svc precedent. The ceiling is enforced by org membership, not by a scope string, and clones are attributable to a named identity. Delivered by warden desk --act paste_once_provision; ops-mason neither minted nor pasted the value. Verified: rapp-openbao, rapp-core-hub, rapp-issue-core and rapp-policy-nexus all read — four of the nine that failed STATE-WP-0083-T04. Push 403, admin API 403, /api/v1/user 403 (the scope carries no read:user). Clone test used GIT_ASKPASS, so no credential entered argv or a clone URL. Records a deviation rather than glossing it: SCOPE.md puts secret values out of scope, and that held for minting and delivery but not for verification — the value was read back to fingerprint it and to run the clone test, under the build-stage disclosure posture agreed 2026-08-27. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 3377672@bnt-lap001 Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
8.5 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | related | state_hub_workstream_id | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| MASON-WP-0003 | workplan | Forge read lane so central can derive private repositories | infotech | ops-mason | active | codex | custodian | 2026-08-26 | 2026-08-26 |
|
4015b46d-02f1-56ac-853e-87e8542cf0dd |
Forge read lane so central can derive private repositories
Goal
Build the credential lane that lets the State Hub read private repositories
from Forgejo, and register it so warden route find answers this question the
next time someone asks it.
This workplan builds the lane. It does not consume it — see the handoff below.
Why this exists
ADR-012 makes the forge the projection source: central clones a repository's
default branch and derives its work records from what Forgejo holds. That works
today because the pod clones anonymously.
It does not work for private repositories. The first fleet-wide reset
(STATE-WP-0083-T04, 2026-08-26) covered 121 repositories and nine failed
identically:
fatal: could not read Username for 'https://forgejo.coulomb.social'
rapp-core-hub, rapp-issue-core, rapp-openbao, rapp-policy-nexus and five
others are invisible to the hub's derivation entirely.
This is a limit on the ADR's own premise. The forge is the projection source holds only for repositories central can read, and nothing in the current design says so.
Why ops-mason owns it
warden route find returns no lane for this need. The nearest entry is
forgejo-admin-api-token — an operator PAT owned by railiance-platform —
which is far more authority than derivation requires and the wrong thing to
reuse.
This repository builds "OpenBao AppRoles, policies, and KV secret paths so ops-warden always has something real to route to", which is exactly what is missing. ops-warden issues SSH certificates only and routes everything else; a Forgejo token is not its to vend.
What ops-mason does not own
Three parts of the end-to-end fix belong to other repositories and are tracked
in state-hub/STATE-WP-0084:
- mounting the credential into the
state-hubdeployment; - teaching
derive_from_forge()to use it, and to distinguish "cannot read" from "does not exist"; - re-running the fleet reset and reviewing the nine first diffs.
STATE-WP-0084-T01 (the unreadable-vs-missing distinction) is not merely
downstream: the recommendation in this lane's construction plan depends on it,
because it is what makes a narrow grant fail visibly. It is worth landing with
or without this credential.
Run the construction plan through the decision gate
id: MASON-WP-0003-T01
status: done
priority: high
state_hub_task_id: "36d26000-ae71-5a58-a563-a07ff5be664f"
plans/state-hub-forge-derivation-read.md holds phases 1–3: the demand, the
existing-structure survey (including why forgejo-admin-api-token is rejected
rather than reused), the proposed AppRole/policy/KV path, the review pass, and
the executive summary.
Three things need deciding, and they determine what the credential can do if it leaks:
- Approve, reject, or send back to phase 1.
- Breadth — organisation-wide repository read, or per-repository. The plan
recommends organisation-wide contingent on
STATE-WP-0084-T01, and argues the counter-case: an organisation-wide token that leaks reads every private repository in the organisation. - Rotation — accept build-phase posture (no scheduled
secret_idexpiry), or require rotation now.
Permission is not in question: derivation performs git clone --depth 1 and
nothing else, so the token gets repository read and no other scope.
Acceptance: the plan reaches status: reviewed, the founder decision is
recorded with its reasoning rather than as a bare value, and the plan carries
approved_by/approved_at.
Done (2026-08-26). Approved by Bernd Worsch, breadth organisation-wide
repository read. The §4 contingency was satisfied first: STATE-WP-0084-T01
landed 2026-08-26, so a repository central may not read now reports as
unreadable and a source that produced no records cannot retire anything even
when retirement is acknowledged — which is what makes a missing grant visible
and, in turn, what the breadth argument rested on. Rotation was not separately
ruled on; build-phase posture stands as proposed. Reasoning in
plans/state-hub-forge-derivation-read.md §6.
Build the AppRole, policy, and KV path structure
id: MASON-WP-0003-T02
status: done
priority: high
state_hub_task_id: "68a1c8e4-c12b-550e-962c-06a90ab8c1c2"
Phase 4, after T01 approval only. Create the OpenBao policy granting read on
exactly one KV path, the KV path structure, and the AppRole the state-hub
workload authenticates with.
ops-mason does not touch the token value, even transiently. The forge owner
mints the read-only Forgejo token; it reaches the KV path through ops-warden's
existing paste_once_provision desk. This task records where the credential
lives and who may read it — never what it is. The value never appears in Git,
State Hub, a workplan, a log, or a chat message.
Acceptance: the policy grants read on that path alone; the AppRole
authenticates and can read nothing else; the KV path exists and the desk has
delivered a working token into it, confirmed by the consumer rather than by
reading the value here. Recorded in audit/build-log.jsonl against the
approved plan.
Done (2026-08-27). Policy workload-kv-read-state-hub-forge-derivation and
Kubernetes auth role state-hub-forge-derivation created and verified; see
plans/state-hub-forge-derivation-read.md §7 and audit/build-log.jsonl.
Kubernetes auth replaces the approved AppRole, ruled at phase 4 after the
live survey found kubernetes/ auth enabled on this cluster — something §2's
disk-only survey could not see. No static role_id/secret_id is created, so
there is nothing to deliver or rotate.
Credential delivered 2026-08-27. Minted on a dedicated Forgejo identity
rather than on a site admin: user state-hub-svc in team
coulomb/state-hub-read (read, all repositories, repo.code unit only), PAT
scoped read:repository. Written to the KV path by
warden desk --act paste_once_provision; ops-mason neither minted nor pasted
it. Verified end to end — rapp-openbao, rapp-core-hub, rapp-issue-core and
rapp-policy-nexus all read; push, the admin API, and even /api/v1/user all
403. See plans/state-hub-forge-derivation-read.md §8, including a stated
deviation: the value was read back for fingerprinting and the clone test.
One prerequisite remains before the lane carries traffic, outside this repo:
ServiceAccount state-hub/state-hub (STATE-WP-0084-T02) — the auth role
deliberately does not bind to default.
Register the lane in the routing catalog
id: MASON-WP-0003-T03
status: progress
priority: high
state_hub_task_id: "e14f0eb3-a920-5623-b4c1-c20858dbb45d"
Propose a pointer-only entry (warden_executes: false, no authored steps,
status: draft) so warden route find "state hub read private repository"
resolves. Its absence is why this had to be reasoned out from first principles
rather than looked up.
The entry names the owner, the subsystem, the KV path, the rotation method, and
states plainly that ops-warden routes but does not execute it. Normal git
contribution to ops-warden, not a live API call.
Acceptance: warden route find returns the lane; warden route show gives an
operator enough to act without reading this workplan.
Drafted 2026-08-26, awaiting contribution to ops-warden (branch
mason/state-hub-forge-derivation-read, commit 3a4333d). Entry
state-hub-forge-derivation-read: pointer-only, warden_executes: false,
status: draft, risk: high — graded on breadth rather than write authority,
since the token is read-only but organisation-wide. Playbook at
wiki/playbooks/state-hub-forge-derivation-read.md, whose verification section
leads with the negative check: the AppRole must be denied on
platform/workloads/forgejo/forgejo-admin, because not being able to do what
the admin lane can is the entire argument for building this one.
registry/generated/high-risk-data-paths.yaml regenerated (21 → 24 lanes); it
had been stale since 2026-08-23, so the regeneration also picks up two
unrelated lanes. Promote the entry to active once T02 has built the structure
and the negative check passes.
Handoff
Once T02 and T03 are done, notify state-hub so STATE-WP-0084-T02 can
unblock. STATE-WP-0084-T01 does not wait on this workplan.