fix(routing): state-hub lane uses Kubernetes auth, not an AppRole
The construction plan proposed an AppRole from a survey written with no OpenBao session. The phase-4 live survey found kubernetes/ auth already enabled on this cluster with four external-secrets-* roles using it, and the founder ruled for it on 2026-08-27. The pod authenticates with its own projected ServiceAccount token, so the lane has no role_id/secret_id to deliver, store, or rotate. Bound to state-hub/state-hub and deliberately not to default, which would grant the lane to every pod in the namespace. Policy and role are built and capability-verified. Entry stays draft: the KV path holds no token until paste_once_provision delivers one, and the ServiceAccount does not exist yet (STATE-WP-0084-T02). 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
This commit is contained in:
parent
6294e4b521
commit
6e66a56653
2 changed files with 21 additions and 9 deletions
|
|
@ -583,7 +583,7 @@ entries:
|
|||
workload_ref:
|
||||
applicability: applicable
|
||||
unknown_reason: "The state-hub deployment has no authoritative workload identity declaration yet; the AppRole is the identity until it does."
|
||||
need_keywords: [state-hub, statehub, forge, forgejo, derivation, derive, projection, private, repository, clone, FORGE_READ_TOKEN, ADR-012, work-records, unreadable]
|
||||
need_keywords: [state-hub, statehub, forge, forgejo, derivation, derive, projection, private, repository, clone, FORGE_READ_TOKEN, ADR-012, work-records, unreadable, kubernetes-auth]
|
||||
owner_repo: ops-mason
|
||||
subsystem: OpenBao + Forgejo
|
||||
warden_executes: false
|
||||
|
|
@ -594,13 +594,13 @@ entries:
|
|||
delegation:
|
||||
mode: native
|
||||
intended_owner: ops-mason
|
||||
blocked_on: "Entry proposed ahead of the build (MASON-WP-0003-T03). Promote to active once MASON-WP-0003-T02 has created the policy, AppRole, and KV path and the negative capability check passes."
|
||||
blocked_on: "Policy and Kubernetes auth role built and capability-verified 2026-08-27 (MASON-WP-0003-T02). Still draft: the KV path holds no token until paste_once_provision delivers one, and ServiceAccount state-hub/state-hub does not exist yet (STATE-WP-0084-T02). Promote to active once both land."
|
||||
reviewed: "2026-08-26"
|
||||
verified: unverified
|
||||
# ops-warden routes this and executes nothing: it issues SSH certificates
|
||||
# only and owns no secret store. ops-mason builds the structure; the forge
|
||||
# owner mints the value; paste_once_provision delivers it.
|
||||
auth_method: "AppRole login (state-hub-forge-derivation) from the in-cluster state-hub workload"
|
||||
auth_method: "Kubernetes auth (role state-hub-forge-derivation, ServiceAccount state-hub/state-hub) from the in-cluster state-hub workload"
|
||||
path_template: "platform/workloads/state-hub/forge-derivation (field FORGE_READ_TOKEN)"
|
||||
rotation:
|
||||
method: rotate
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# State Hub Forge Derivation Read Token
|
||||
|
||||
Date: 2026-08-26 (proposed)
|
||||
Catalog: `state-hub-forge-derivation-read` (status `draft` until built)
|
||||
Date: 2026-08-26 (policy and auth role built and verified 2026-08-27)
|
||||
Catalog: `state-hub-forge-derivation-read` (status `draft` until the token and ServiceAccount land)
|
||||
Owner: `ops-mason` (built under `ops-mason/plans/state-hub-forge-derivation-read.md`, approved 2026-08-26)
|
||||
|
||||
Read-only Forgejo token so the State Hub can clone **private** repositories and
|
||||
|
|
@ -27,7 +27,7 @@ delivered through `paste_once_provision`.
|
|||
| Path | `platform/workloads/state-hub/forge-derivation` |
|
||||
| Secret field | `FORGE_READ_TOKEN` |
|
||||
| Policy | `workload-kv-read-state-hub-forge-derivation` (read on that path alone) |
|
||||
| AppRole | `state-hub-forge-derivation` (`token_ttl=15m`, `token_max_ttl=30m`) |
|
||||
| Auth | Kubernetes auth role `state-hub-forge-derivation`, bound to ServiceAccount `state-hub/state-hub` (`token_ttl=15m`, `token_max_ttl=30m`) |
|
||||
|
||||
**Forgejo token scope:** repository **read**, organisation-wide. No push, no
|
||||
administration, no other Forgejo resource. Approved at that breadth on
|
||||
|
|
@ -69,15 +69,27 @@ projection that only reads must not hold an identity that can write.
|
|||
## Verify the lane (capabilities-safe — never read the value)
|
||||
|
||||
```bash
|
||||
# Positive: the AppRole identity can read the data path
|
||||
bao token capabilities <approle-token> platform/data/workloads/state-hub/forge-derivation
|
||||
# Positive: the lane identity can read the data path
|
||||
bao token capabilities <lane-token> platform/data/workloads/state-hub/forge-derivation
|
||||
# → expect: read
|
||||
|
||||
# Negative: it can read nothing else, including the admin lane
|
||||
bao token capabilities <approle-token> platform/data/workloads/forgejo/forgejo-admin
|
||||
bao token capabilities <lane-token> platform/data/workloads/forgejo/forgejo-admin
|
||||
# → expect: deny
|
||||
```
|
||||
|
||||
Verified 2026-08-27 through a 2-minute test token, revoked after use: `read` on
|
||||
its own path; `deny` on `forgejo-admin`, on the shared `llm-connect` provider
|
||||
secrets, and on the parent metadata path (no listing).
|
||||
|
||||
**Why Kubernetes auth and not an AppRole.** The construction plan proposed an
|
||||
AppRole; the phase-4 live survey found `kubernetes/` auth already enabled on
|
||||
this cluster, and the founder ruled for it on 2026-08-27. The pod authenticates
|
||||
with its own projected ServiceAccount token, so this lane has no `role_id`
|
||||
/`secret_id` pair to deliver, store, or rotate. The role binds to
|
||||
`state-hub/state-hub` and deliberately **not** to `default`, which would grant
|
||||
the lane to every pod in the namespace.
|
||||
|
||||
The negative check is the one that matters. The whole argument for building this
|
||||
lane instead of reusing `forgejo-admin-api-token` is that it cannot do what that
|
||||
one can.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue