cust81-forge-reader-r1.jsonl records reader_scope seven_exact_no_extra_private_grants for attempt bb2693a7640f00b4e401467e. That status is written only after the excluded private repo, admin route, and Actions routes are refused. The workplan is finished. The plan stays reviewed. Assistant: grok Assistant-Session: 01a16071-5425-78d3-80b4-20fe2ee30f0a
479 lines
30 KiB
Markdown
479 lines
30 KiB
Markdown
---
|
||
id: reuse-surface-private-source-reader
|
||
revision: 2
|
||
proposal_id: MASON-CUST81-PRIVATE-READER-R1
|
||
demand_source: the-custodian/workplans/CUST-WP-0081-netkingdom-architecture-review-and-reuse.md
|
||
consumer_repo: reuse-surface
|
||
credential_type: forgejo-restricted-source-read-with-existing-kubernetes-eso
|
||
status: reviewed
|
||
approved_by: null
|
||
approved_at: null
|
||
created: "2026-10-15"
|
||
updated: "2026-10-22"
|
||
construction_inputs: builds/reuse-surface-private-source-reader/construction-inputs.json
|
||
candidate_spec_sha256: 59a7334eb58135790547fab0a8c8e8debb94cc7acaae88d30654c9ae887d6732
|
||
approved_spec_sha256: null
|
||
filed_as: null
|
||
---
|
||
|
||
# Construction plan: seven-repository hosted capability reader
|
||
|
||
## 1. Demand
|
||
|
||
The reuse-surface hub has established 63 of the 70 reviewed security capabilities.
|
||
It needs authenticated reads of the seven remaining private repository indexes.
|
||
The founder explicitly approved only public disclosure of the exact capability
|
||
metadata in CUST81-PRIVATE-METADATA-DISCLOSURE-R1; repository source remains
|
||
private. This plan proposes a dedicated repository reader for the hosted process
|
||
and delivery through its existing namespace-bound ESO identity. Credential access
|
||
and live changes require their own reviewed exact-revision approval.
|
||
|
||
Preparation source is CUST81-PRIVATE-READER-PROVISIONING-PREPARATION-R1, SHA256
|
||
`7819eb51d249f5c7aff4df9fb520afcfb76603b05a4104439499102b6c20af99`.
|
||
Consent receipt SHA256 is
|
||
`4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52`;
|
||
disclosure packet SHA256 is
|
||
`46ac4fe49a08054cc215aade2fbaf3b36ee334520997857ed84f530b52da9d35`.
|
||
The bundled construction-inputs retain all seven consented commits, index hashes
|
||
and native raw API URLs. These references contain no credential values.
|
||
|
||
The 2026-10-15 preparation did not survey OpenBao. Section 2 now records the
|
||
2026-10-21T22:15:21Z metadata survey under grant
|
||
`token-claude-MASON-WP-0014-T04` (policies `default`, `ops-mason-survey`).
|
||
This file is `reviewed`. It is not an ops-mason approval to mint or apply.
|
||
|
||
## 2. Existing-structure survey
|
||
|
||
Generated by `scripts/plan-survey.py` at 2026-10-21T22:15:21Z against `BAO_ADDR=http://127.0.0.1:18200`, token display_name `token-claude-MASON-WP-0014-T04` (policies: default, ops-mason-survey). Metadata only: no `kv get` and no `*/data/*` read was issued; policy bodies were read with `bao policy read` for name-matched candidates only.
|
||
|
||
Demand: KV path `platform/workloads/reuse/reuse-surface/forgejo-source-read`, proposed policy `workload-kv-read-reuse-surface-runtime-eso`, AppRole `-`, Kubernetes role `reuse-surface-runtime-eso`, consumer `reuse-surface`. Match terms: `reuse-surface`, `reuse-surface-runtime-eso`, `forgejo`, `reuse-surface-source`, `reuse`, `forgejo-source-read`.
|
||
|
||
### `bao secrets list` (10 mounts, 1 relevant)
|
||
|
||
```text
|
||
platform/ kv version=2
|
||
```
|
||
|
||
### `bao auth list` (6 auth mounts, 2 relevant)
|
||
|
||
```text
|
||
approle/ approle
|
||
kubernetes/ kubernetes
|
||
```
|
||
|
||
### `bao policy list` (95 policies, 9 relevant)
|
||
|
||
```text
|
||
workload-kv-read-agent-harness-forgejo matches: forgejo
|
||
workload-kv-read-core-hub-forgejo-source matches: forgejo
|
||
workload-kv-read-forgejo-admin matches: forgejo
|
||
workload-kv-read-forgejo-mailer matches: forgejo
|
||
workload-kv-read-forgejo-mailer-eso matches: forgejo
|
||
workload-kv-read-keycape-forgejo-eso matches: forgejo
|
||
workload-kv-read-policy-nexus-forgejo-source matches: forgejo
|
||
workload-kv-read-reuse-surface-runtime matches: reuse-surface, reuse
|
||
workload-kv-read-reuse-surface-runtime-eso matches: reuse-surface, reuse-surface-runtime-eso, reuse, proposed name
|
||
```
|
||
|
||
### `bao list auth/approle/role` (approle) (14 roles, 0 relevant)
|
||
|
||
```text
|
||
(no relevant entries)
|
||
```
|
||
|
||
### `bao list auth/kubernetes/role` (kubernetes) (36 roles, 5 relevant)
|
||
|
||
```text
|
||
external-secrets-core-hub-forgejo-source matches: forgejo
|
||
token_policies=['workload-kv-read-core-hub-forgejo-source']
|
||
policies=['workload-kv-read-core-hub-forgejo-source']
|
||
token_ttl=900
|
||
token_max_ttl=0
|
||
token_num_uses=0
|
||
bound_service_account_names=['external-secrets']
|
||
bound_service_account_namespaces=['external-secrets']
|
||
external-secrets-keycape-forgejo matches: forgejo
|
||
token_policies=['workload-kv-read-keycape-forgejo-eso']
|
||
policies=['workload-kv-read-keycape-forgejo-eso']
|
||
token_ttl=900
|
||
token_max_ttl=900
|
||
token_num_uses=0
|
||
bound_service_account_names=['external-secrets']
|
||
bound_service_account_namespaces=['external-secrets']
|
||
audience=openbao
|
||
external-secrets-reuse-surface matches: reuse-surface, reuse
|
||
token_policies=['workload-kv-read-reuse-surface-runtime']
|
||
policies=['workload-kv-read-reuse-surface-runtime']
|
||
token_ttl=900
|
||
token_max_ttl=0
|
||
token_num_uses=0
|
||
bound_service_account_names=['external-secrets']
|
||
bound_service_account_namespaces=['external-secrets']
|
||
forgejo-mailer-eso matches: forgejo
|
||
token_policies=['workload-kv-read-forgejo-mailer-eso']
|
||
token_ttl=900
|
||
token_max_ttl=900
|
||
token_num_uses=0
|
||
bound_service_account_names=['forgejo-mailer-eso']
|
||
bound_service_account_namespaces=['forgejo']
|
||
audience=openbao
|
||
reuse-surface-runtime-eso matches: reuse-surface, reuse-surface-runtime-eso, reuse, proposed name
|
||
token_policies=['workload-kv-read-reuse-surface-runtime-eso']
|
||
token_ttl=900
|
||
token_max_ttl=900
|
||
token_num_uses=0
|
||
bound_service_account_names=['reuse-surface-eso']
|
||
bound_service_account_namespaces=['reuse']
|
||
audience=openbao
|
||
```
|
||
|
||
### `bao policy read` of name-matched candidates (target `platform/data/workloads/reuse/reuse-surface/forgejo-source-read`)
|
||
|
||
```text
|
||
workload-kv-read-agent-harness-forgejo: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-core-hub-forgejo-source: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-forgejo-admin: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-forgejo-mailer: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-forgejo-mailer-eso: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-keycape-forgejo-eso: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-policy-nexus-forgejo-source: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-reuse-surface-runtime: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read
|
||
workload-kv-read-reuse-surface-runtime-eso: path "platform/data/workloads/reuse/reuse-surface/forgejo-source-read" capabilities=['read']
|
||
```
|
||
|
||
### `bao kv metadata get` / `bao kv list` (metadata only)
|
||
|
||
```text
|
||
platform/workloads/reuse/reuse-surface/forgejo-source-read: exists, current_version=1, created=2026-10-15, updated=2026-10-15
|
||
platform/workloads/reuse/reuse-surface/: forgejo-source-read, runtime-secrets
|
||
```
|
||
|
||
### ops-warden routing catalog `/home/worsch/ops-warden/registry/routing/catalog.yaml` (49 entries, 8 relevant)
|
||
|
||
```text
|
||
whynot-design-npm-publish owner=railiance-platform status=active matches: forgejo
|
||
path_template: platform/workloads/coulomb/whynot-design/npm-publish
|
||
policy_ref: flex-auth check secret.read:whynot-design
|
||
auth_method: bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
|
||
policy-nexus-forgejo-source-read owner=railiance-platform status=active matches: forgejo, forgejo-source-read
|
||
path_template: platform/workloads/policy-nexus/forgejo-source-read
|
||
policy_ref: flex-auth check secret.read:policy-nexus
|
||
auth_method: bao login -method=oidc -path=netkingdom role=policy-nexus-forgejo-source-workload-kv-read
|
||
core-hub-forgejo-source-read owner=railiance-platform status=active matches: forgejo, forgejo-source-read
|
||
path_template: platform/workloads/core-hub/forgejo-source-read
|
||
policy_ref: workload-kv-read-core-hub-forgejo-source
|
||
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)
|
||
reuse-surface-hub-write-token owner=railiance-platform status=active matches: reuse-surface, forgejo, reuse
|
||
path_template: platform/workloads/reuse/reuse-surface/runtime-secrets
|
||
policy_ref: flex-auth check secret.read:reuse
|
||
auth_method: bao login -method=oidc -path=netkingdom role=reuse-surface-hub-writer-workload-kv-read
|
||
railiance-backup-offsite-lane owner=railiance-platform status=active matches: forgejo
|
||
path_template: platform/workloads/railiance/backup/offsite-lane
|
||
auth_method: caller's own OpenBao token (OIDC netkingdom role railiance-backup-workload-kv-read)
|
||
state-hub-forge-derivation-read owner=ops-mason status=active matches: forgejo
|
||
path_template: platform/workloads/state-hub/forge-derivation (field FORGE_READ_TOKEN)
|
||
auth_method: Kubernetes auth (role state-hub-forge-derivation, ServiceAccount state-hub/state-hub) from the in-cluster state-hub workload
|
||
forgejo-admin-api-token owner=railiance-platform status=active matches: forgejo
|
||
path_template: platform/workloads/forgejo/forgejo-admin
|
||
auth_method: caller's own OpenBao token (OIDC netkingdom role forgejo-admin-workload-kv-read)
|
||
agent-harness-forgejo-deploy owner=railiance-platform status=active matches: forgejo
|
||
path_template: platform/workloads/agent-harness/forgejo-deploy-key
|
||
policy_ref: flex-auth check secret.read:agent-harness-forgejo
|
||
auth_method: caller's own OpenBao token (policy workload-kv-read-agent-harness-forgejo) or host-local key at ~/.local/agent-harness/ssh/forgejo-deploy
|
||
```
|
||
|
||
### Does an existing lane already satisfy this demand?
|
||
|
||
**Decision (survey 2026-10-21T22:15:21Z): the OpenBao delivery lane already matches.** Edited from the generated "yes".
|
||
|
||
- KV `platform/workloads/reuse/reuse-surface/forgejo-source-read` exists, `current_version=1`, created and updated 2026-10-15. No data body was read.
|
||
- Policy `workload-kv-read-reuse-surface-runtime-eso` is the only name-matched policy that grants `read` on `platform/data/workloads/reuse/reuse-surface/forgejo-source-read`.
|
||
- Kubernetes role `reuse-surface-runtime-eso` exists: `token_policies=['workload-kv-read-reuse-surface-runtime-eso']`, SA `reuse-surface-eso`, namespace `reuse`, audience `openbao`, ttl and max ttl 900.
|
||
- The caller writer policy `workload-kv-read-reuse-surface-runtime` has no stanza for that path. The other name-matched Forgejo policies do not either. Catalog entries `core-hub-forgejo-source-read`, `policy-nexus-forgejo-source-read`, `reuse-surface-hub-write-token`, and `forgejo-admin-api-token` are different paths.
|
||
- The survey grant's own capabilities on that data path and on `platform/data/workloads/reuse/reuse-surface/runtime-secrets` are `deny`. Metadata read on the reader path is `list, read`.
|
||
- One grant file was present, display name `token-claude-MASON-WP-0014-T04`. It is an `ops-mason-survey` grant. It is not an operator or admin token. A second file named for MASON-WP-0013-T02 was not minted.
|
||
|
||
### Forgejo-owner Q1–Q3
|
||
|
||
`the-custodian` `owner-assembly/forge-final-r2/review/forge-owner-review-r2.json`, reviewer `railiance-forge-owner (agent railiance-forge, codex)`, `reviewed_at` 2026-10-14T23:08:34Z, `sec_dsm_order`:
|
||
|
||
- Q1: no direct Kubernetes identity accepted by the current raw HTTP route is demonstrated.
|
||
- Q2: KeyCape human login does not establish machine API federation; no installed workload JWT trust is demonstrated.
|
||
- Q3: upstream Forgejo OAuth can issue expiring access tokens, but only `authorization_code` and `refresh_token`; no viable workload `client_credentials` or token exchange is demonstrated. A static fallback is conditional.
|
||
|
||
That review is the Forgejo owner's hierarchy text. It is not founder authorization. Disclosure consent is a different record.
|
||
|
||
## 3. Proposed changes
|
||
|
||
### SEC-DSM §37 decision procedure, in order
|
||
|
||
1. **Q1 — native identity:** the current native raw HTTP fetch uses an
|
||
Authorization credential; Kubernetes SA identity alone is not demonstrated
|
||
as accepted by this Forgejo route. Candidate answer: no for the current
|
||
consumer interface, subject to Forgejo/reuse owner confirmation. Anonymous
|
||
access would require private visibility change and does not satisfy demand.
|
||
2. **Q2 — federation:** human KeyCape OIDC login does not prove a machine-token
|
||
exchange for these raw API requests. No workload federation exchange for this
|
||
target is evidenced by the local source review. Candidate answer: no viable
|
||
installed interface demonstrated; Forgejo owner must confirm or supply a
|
||
higher mechanism. If supported reliably, revise to federation before approval.
|
||
3. **Q3 — ephemeral target credential:** the local CCR-0031 precedent states PATs
|
||
have no server-side expiry. No usable ephemeral Forgejo issuance/revocation
|
||
service is evidenced. Candidate answer: no mechanism demonstrated, pending
|
||
target-owner confirmation. Do not add a broker just to label a static PAT
|
||
dynamic (DSM-TRANS-003). ESO's 15-minute Bao token does not expire the PAT.
|
||
4. **Q4 — automatic rotation:** do not reuse an existing broader PAT. No automated
|
||
rotation job for this proposed dedicated identity is evidenced. Provisioning
|
||
capability is not automatic lifecycle enforcement. Answer: not demonstrated;
|
||
proposed attended rotation is explicitly manual, owned and dated.
|
||
5. **Q5 — residual static credential:** conditional on Q1–Q3 owner confirmation,
|
||
use a centrally governed dedicated PAT, OpenBao as custody authority, Forgejo
|
||
as grant/revocation authority, ESO/Kubernetes/env as delivery copies. Level 5
|
||
in §5, **centrally managed static secret**, not level 3 or 4. No AppRole is
|
||
needed: the existing ESO projected workload identity authenticates to Bao.
|
||
|
||
These answers follow DSM-ARCH-001–004, DSM-TRANS-002/003, DSM-K8S-001–004 and
|
||
§35/36: use existing projected SA identity for delivery, avoid adding a static
|
||
ESO token or broker, and distinguish central custody from delivery copies.
|
||
Unconfirmed Q1–Q3 are explicit review gates, not asserted facts.
|
||
|
||
### Exact object changes and boundaries
|
||
|
||
- **create** restricted private non-admin Forgejo user `reuse-surface-source`;
|
||
**create** org team `coulomb/reuse-surface-source-readers`. Dedicated target
|
||
identity replaces unsuitable broad readers identified in §2. Team permission
|
||
`read`, `includes_all_repositories=false`, `can_create_org_repo=false`, only
|
||
`repo.code=read`; all non-code units `none`. Team members exactly this user.
|
||
- **create** team membership for exactly `coulomb/rapp-openbao`,
|
||
`coulomb/rapp-policy-nexus`, `coulomb/rapp-postgres`, `coulomb/rapp-sbom-nexus`,
|
||
`coulomb/rapp-telemetry`, `coulomb/rapp-tenant-engine`, `coulomb/rapp-user-engine`.
|
||
Follow all API pages and inspect effective user grants, other teams, direct
|
||
collaborator access, organisation membership and repository ownership. Adding
|
||
seven repositories without checking extra effective grants is insufficient.
|
||
Existing identity/team with differing configuration is a conflict, not permission
|
||
to remove unrelated access silently. Reconciliation needs a revised plan.
|
||
- **create** dedicated PAT named `reuse-surface-source-read-<UTC-attempt>` with
|
||
scopes exactly `[read:repository]`. Platform-owned attended helper holds values
|
||
in memory, suppresses every raw response/error and returns token IDs only.
|
||
Password used for service bootstrap is random memory-only, never persisted
|
||
in evidence or reused as workload authentication. Prevent unattended password
|
||
login and recovery escalation according to Forgejo owner review.
|
||
- **create** KV-v2 entry `platform/workloads/reuse/reuse-surface/forgejo-source-read`,
|
||
field `FORGEJO_SOURCE_TOKEN`. Platform alone provisions value through its
|
||
reviewed silent custody route from stdin; ops-mason does not handle the value.
|
||
It must retain accessor/token ID and custody version in sanitized lifecycle
|
||
inventory. A new path separates private reader from attended writer callers.
|
||
- **modify** only existing policy `workload-kv-read-reuse-surface-runtime-eso` by
|
||
adding `read` on exact
|
||
`platform/data/workloads/reuse/reuse-surface/forgejo-source-read`.
|
||
Candidate full file is bundled, SHA256
|
||
`788bb9c49ab571e522beeecf7a5e29d1c79c842a84fe6d801978655facd3b5bd`.
|
||
No glob, metadata grant, other sibling, caller writer policy, OIDC binding,
|
||
AppRole or Kubernetes auth role change. Verify role/token is still 15m and
|
||
bound to exact SA/namespace/audience; source configuration is not live proof.
|
||
- **modify** existing `reuse/reuse-surface-runtime` ExternalSecret by one data
|
||
item: secretKey `REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN`, remoteRef key
|
||
`workloads/reuse/reuse-surface/forgejo-source-read`, property
|
||
`FORGEJO_SOURCE_TOKEN`. Bundled JSON item is a proposal for apps integration,
|
||
not a standalone apply object. Preserve existing writer and webhook fields.
|
||
- **modify** native fetch code/image through reuse and apps review: reuse owner
|
||
identified both Authorization header forwarding on redirects and registration-
|
||
controlled auth_env/URL credential exfiltration in the current native fetch.
|
||
Do not project the PAT until the full reviewed fix is image-digest pinned and
|
||
runtime authorization plus redirect credential isolation are verified.
|
||
Then deliver through existing envFrom and an apps-approved controlled rollout.
|
||
Image change is explicit; preserve resource bounds unless separately reviewed.
|
||
Rollout must account for SQLite/PVC and single-node headroom before approval.
|
||
- **modify** owner-controlled runtime config `REUSE_SURFACE_AUTH_SOURCE_ALLOWLIST`
|
||
to map `REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN` to the exact fourteen consented
|
||
pinned API URL strings: seven indexes and seven capability entries. Candidate
|
||
config is `builds/reuse-surface-private-source-reader/auth-source-allowlist.json`;
|
||
registrations cannot set or widen this runtime authority. The patched consumer
|
||
checks exact URL membership **before credential lookup**, requires HTTPS and
|
||
refuses authenticated redirects including same-origin path changes. Apps/reuse
|
||
must safely inventory existing authenticated registrations (auth_env and URL
|
||
metadata only), review which destinations remain legitimate, and migrate their
|
||
mappings before fail-closed rollout. Inventory is not blanket consent. The new
|
||
reader mapping stays exact14; any existing legitimate other mapping needs its
|
||
own owner-reviewed authorization. Missing/invalid mappings fail closed.
|
||
- **create** proposed ops-warden pointer `reuse-surface-forgejo-source-read` in
|
||
draft status after construction, owner `railiance-platform`, non-SSH route
|
||
only (`warden_executes:false`). Runtime reader is the hub, not warden.
|
||
Activation remains ops-warden's independent verified catalog review.
|
||
|
||
### Full consumer candidate pins
|
||
|
||
Reuse owner provided full patch SHA256
|
||
`f707ddfd36d5d470c176530671bb30ff6a3af2dfff86937aa8a5618bcb79768e`,
|
||
fixed `federation.py` SHA256
|
||
`dbaa40f25cc0f090143578cd1c7068cb2cb00960fafd17d5239bf8a5bac514dd`,
|
||
native verification helper `private_source_verify.py` SHA256
|
||
`c67a284091cc4dd62dca56658a14b8ea1357e2b3df1518120da4c51e0ee8d85c`,
|
||
and owner runtime allowlist SHA256
|
||
`e1948c537e206b30fc72b9e4732a3f600d92e131813e6f7ecfd4bfbb18c27286`.
|
||
The ops-mason bundled compact allowlist has the same exact env and fourteen URL
|
||
sets; serialization/order differs. The construction inputs retain absolute
|
||
isolated-owner artifact references for integration. Owner reports focused30pass
|
||
and whole226pass with one isolated-relative-path failure; this is not native
|
||
runtime proof. Fixed image digest and owner execution review remain pending.
|
||
|
||
### Revision preservation
|
||
|
||
R2 refines the same proposal and trial; R1 is preserved under custodian
|
||
`owner-assembly/mason-r1/` and `/tmp/cust81-mason-reader-r1-snapshot`. R1 candidate
|
||
spec digest was `0d1f604c76e086c82675dc535004cf4da51ef5dc247959fab50295a673407980`.
|
||
Neither revision was approved or executed. The full consumer fix and runtime
|
||
allowlist supersede the earlier redirect-only image gate. Approval, when sought,
|
||
must bind this final reviewed revision, its consumer patch, runtime config and
|
||
image; do not create another scored trial from this refinement.
|
||
|
||
### Residual-secret lifecycle and elimination
|
||
|
||
Credential owner is railiance-platform; Forgejo owns target grants; reuse-surface
|
||
is the only workload consumer. Authority exposes **entire source code of the
|
||
seven repositories**, not just registry files. Metadata disclosure approval
|
||
alone does not authorize this larger repository-read grant.
|
||
|
||
Known intended copies: OpenBao KV current version and retained versions/backups;
|
||
Kubernetes Secret in `reuse` and etcd backups; hub process environment; transient
|
||
minting/delivery memory. Every namespace actor allowed to attach the ESO store or
|
||
reference the materialized Secret is an indirect consumer/exposure path and must
|
||
be reviewed; namespace conditions are not per-pod isolation. No CI/chat/local
|
||
credential file copy is allowed. Avoid Secret last-applied annotation copies.
|
||
|
||
Proposed lifetime policy is attended rotation **every 90 days**, and immediately
|
||
on compromise, owner change, consumer retirement or scope drift. This is a
|
||
recommended stricter policy than CCR-0031's 180-day precedent; it is not a claim
|
||
of automated enforcement or PAT native expiry. Record issuance and next-due UTC
|
||
in platform inventory, with an assigned owner reminder before activation.
|
||
Rotation: mint one replacement with the same checked grant; compare scopes and
|
||
all effective grants; write it as a new KV version without changing other fields;
|
||
wait for ESO, roll the reviewed fixed image, verify all seven native fetches, then revoke old
|
||
PAT by recorded ID. Replacement overlap must end within 24 hours. Failed or
|
||
ambiguous replacement issuance is reconciled by token-name/ID inventory before
|
||
retry; no blind minting. Review retained KV versions/backups under platform's
|
||
retention policy; obsolete token copies are harmless only after target revocation.
|
||
|
||
Immediate revocation deletes the dedicated PAT by ID, then removes/disables only
|
||
this identity's team grants as approved. Compromise response reviews Forgejo
|
||
access/audit metadata and scans owned repositories and approved logs for leaks
|
||
without placing tokens in prompts. Use secret scanners/redactors and suppressed
|
||
negative probes. Availability strategy fails private refresh closed and marks
|
||
consented cache stale; public discovery continues. Never substitute privileged
|
||
personal/admin/core-hub credentials during issuer outage.
|
||
|
||
Elimination depends on Forgejo/native federation or an operationally viable
|
||
short-lived service credential, plus native consumer support. Revisit at rotation
|
||
and at target upgrades; retain a live owner record for that engineering debt.
|
||
|
||
## 4. Review notes (ops-mason phase 2, incomplete)
|
||
|
||
Reuse existing delivery identity and stores rather than introduce AppRole/static
|
||
ESO authority. The new PAT is isolated; caller writer policy stays byte-identical.
|
||
The proposed full ESO policy preserves every original byte before one added exact
|
||
read stanza; integration must compare current live and source digests. If policy
|
||
changed, rebase, review and pin a fresh digest rather than overwrite it.
|
||
|
||
Existing `ops_mason.executor` engines do not express Forgejo user/team/PAT and
|
||
shared-policy extension. Do not mislabel this JSON as a supported build_spec or
|
||
pass it to a single-KV builder: that could replace existing policy. Candidate
|
||
spec digest is SHA256 of UTF-8 sorted compact JSON with allow_nan=false. It
|
||
binds scope; it is neither approval nor an executable adapter. Platform must
|
||
allocate CCR, own a silent idempotent provisioner and pin all execution/artifact
|
||
inputs before phase 3. Approval of a construction plan does not supply a token.
|
||
|
||
The OpenBao structure survey and the Forgejo-owner Q1–Q3 citation are in §2.
|
||
Platform CCR-2026-0046 and founder decision
|
||
`9833715e-a22a-45c0-ab6c-881f0f4f1a0e` are recorded on MASON-WP-0013-T03.
|
||
ops-mason does not mint, approve, or apply from this file.
|
||
|
||
## 5. Executive summary (candidate; not yet ready for approval)
|
||
|
||
1. **One-line ask.** Give the hosted capability hub a dedicated read-only account
|
||
for the seven private repositories whose capability metadata you consented
|
||
to publish, delivered using the existing workload-identity path.
|
||
2. **Who/what gets access.** Forgejo user `reuse-surface-source` obtains the
|
||
seven-repository read grant; the existing `reuse-surface-runtime-eso` identity
|
||
reads one additional exact custody entry for the hub. Namespace actors able
|
||
to reuse the delivery store/Secret remain an exposure consideration to review.
|
||
3. **To what.** Read-only source access across the seven named private repositories,
|
||
with no write/admin/non-code-unit grants. The hub publishes only the pinned
|
||
consented capability metadata; repository visibility stays private.
|
||
4. **For how long.** Bao delivery tokens remain 15 minutes, but the Forgejo PAT
|
||
has no expiry demonstrated. Proposed attended rotation is every 90 days with
|
||
immediate revocation on compromise; this distinction must be accepted explicitly.
|
||
5. **Blast radius if the credential leaks.** Entire private source of those seven
|
||
repositories can be read. The token must have no additional private-repository
|
||
access and cannot write. Metadata disclosure consent is narrower than that read
|
||
grant. Availability impact of controlled rollout remains owner-reviewed.
|
||
6. **Cost to reverse.** Revoke one PAT, remove only its dedicated grants, remove
|
||
one new ESO data item and one new policy stanza, and roll the reviewed fixed image.
|
||
Reconcile private registrations from the exact attempt; preserve the existing
|
||
public capabilities and writer/webhook keys. No additional paid infrastructure
|
||
is proposed (incremental estimate EUR 0); labor and credible loss remain unpriced,
|
||
so this stays supervised.
|
||
|
||
Founder decision `9833715e-a22a-45c0-ab6c-881f0f4f1a0e` (resolved 2026-10-15,
|
||
Bernd Worsch) binds execution revision SHA256
|
||
`704a9c932202fc14456652ea4dfdb3acb8b1db0ab3bbf5fff50e92b2c517c380`.
|
||
Disclosure-consent digest
|
||
`4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52` is a
|
||
different record. This file stays `reviewed`. ops-mason does not set it
|
||
`approved` and does not apply it.
|
||
|
||
## 6. Proposed verification and rollback contract
|
||
|
||
The contract below is the acceptance rule. The platform path already ran.
|
||
ops-mason's 2026-10-21 metadata receipt, the seven-index receipt, the 70-id
|
||
receipt, and the reader-scope journal are on MASON-WP-0013-T04. The draft
|
||
catalog proposal is not activated. No secret value is in those records.
|
||
|
||
Before changes: exact CCR/plan/script/manifest digests, owner reviews and founder
|
||
approved revision must match; metadata survey proves current path/policy/role;
|
||
source/consent pins match; all existing user/team conflicts resolved; previous
|
||
policy and deployment revision retained; apps runs dry-run and client diff,
|
||
confirms target node and headroom/PVC strategy. Never read or print Secret objects.
|
||
|
||
Before projecting any PAT into the hub: reuse owner patch must close native
|
||
both redirect Authorization forwarding and registration-controlled auth_env/URL
|
||
exfiltration. Tests must prove unlisted URL refusal before credential lookup and
|
||
no redirect credential forwarding. Apps must pin the full fixed image and exact
|
||
runtime allowlist configuration; review/migrate existing authenticated sources
|
||
before rollout. The earlier same-image and redirect-only assumptions are
|
||
superseded; full fixed image/source/patch and owner-runtime config approval remain
|
||
pending. The candidate allowlist encodes the consent packet exact fourteen URLs.
|
||
|
||
After target issuance, scope metadata must be exactly read:repository, team repo
|
||
set exactly seven and complete effective grants enumerated. Choose a known private
|
||
outside repo by target-owner metadata and prove denial without body retention.
|
||
Use safe read-only negative admin/non-code routes; never try writes as a negative
|
||
probe because unexpected privilege could make them succeed. Verify absence of
|
||
write authority through scope and effective permissions. Missing auth/anonymous
|
||
private raw reads fail closed, never cached as fresh successes.
|
||
|
||
Bao positive receipt proves ESO role exact path read; negative receipts prove
|
||
default identity and dedicated caller writer cannot read the new path, ESO cannot
|
||
read an unrelated sibling, and wrong SA/namespace/audience cannot authenticate.
|
||
These are effective token-specific checks, not a test on an admin session.
|
||
Owner suppressing helper checks ESO Ready and materialized key presence only.
|
||
|
||
In the actual running hub, native `fetch_remote_index_text` must fetch all seven
|
||
pinned URLs using `REUSE_SURFACE_FORGEJO_SOURCE_READ_TOKEN` and native header code;
|
||
validate schema, exact index hashes, exact expected IDs and relative entry handling
|
||
without printing private bodies. Local curl success is insufficient for native
|
||
runtime verification. Then register seven pinned sources with the approved writer
|
||
lane and force fresh composition; prove all 70 reviewed IDs exactly once, no stale
|
||
private fallback and matching metadata. Public URLs/entries and source bytes must
|
||
stay inside disclosure consent; new commits need renewed metadata review.
|
||
|
||
Rollback order: immediately revoke dedicated PAT; disable only new private
|
||
registrations after reconciling ambiguous requests; remove/revert exact new
|
||
ESO data item and policy stanza through owner paths; remove only the new
|
||
materialized token key with a suppressing helper, preserve writer/webhook keys;
|
||
controlled approved-image rollout. A previously vulnerable image must never
|
||
receive the new reader key; verify key removal before restoring such an image.
|
||
Restore previous pinned policy/deployment revision
|
||
when applicable. Retain partial, failed and unverified outcomes and token IDs.
|
||
Do not delete the shared Secret/store/role, overwrite unrelated policy changes,
|
||
or remove all public registrations. Restore only the new reader runtime mapping,
|
||
preserving separately reviewed existing authenticated-source mappings. No transactional rollback is claimed.
|