Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 692292@bnt-lap001 Assistant-Session: 89c7d8e8-e1b3-47eb-9411-a0ab227fca2f
5.4 KiB
Activity Core repo-manager Forgejo read lane (CCR-2026-0034, number to confirm)
Status: proposed, drafted 2026-10-04 for STATE-WP-0094 memo 3
(freshness-runner-deploy-trial-e77f8b4, accepted by the founder 2026-10-04,
approval 4ae04c8e) and RMGR-WP-0020-T04. Nothing here is approved, applied or
provisioned. No Forgejo, OpenBao or cluster object was created. Confirm the CCR
number with the CCR tooling before registering; 0033 was the highest seen.
Why
The bounded freshness runner (rmgr freshness run, repo-manager e77f8b4)
runs inside the Activity Core worker (activity-core/actcore-worker). It reads
each repository's default-branch HEAD through the Forgejo API at
forgejo.coulomb.social/coulomb/<slug>. Anonymous reads fail on private
repositories, which the runner records as a refusal and which stops the memo 3
trials. warden route find (2026-10-04) has no route for this workload:
state-hub-forge-derivation-readis bound to SAstate-hub/state-hubonly.core-hub-forgejo-source-read(CCR-2026-0031) andpolicy-nexus-forgejo-source-read(CCR-2026-0014) are bound to other namespaces.
Reusing any of them would share one identity across workloads, which the CCR-2026-0014 and CCR-2026-0031 precedent avoids. This lane gives the runner its own read-only identity.
Shape
| Item | Value |
|---|---|
| Forgejo user | activity-core-freshness (restricted, non-admin, private; random unrecorded password) |
| Forgejo team | coulomb/activity-core-freshness-readers: permission read, all repositories, repo.code read, every other unit none, cannot create repos |
| PAT | activity-core-freshness-read-<UTC timestamp>, scope exactly read:repository |
| OpenBao | platform/workloads/activity-core/repo-manager-forgejo-read fields FORGEJO_READ_TOKEN, API_USER, API_BASE_URL, TOKEN_SCOPES, GENERATED_AT |
| Policy | workload-kv-read-activity-core-repo-manager-forgejo (read on data + metadata of that one path) |
| Auth | Kubernetes role external-secrets-activity-core-repo-manager-forgejo, bound to SA external-secrets/external-secrets, TTL 15m |
| Delivery | ExternalSecret activity-core/actcore-repo-manager-forgejo-read → separate Secret, key FORGEJO_READ_TOKEN. Never merged into actcore-runtime-secret, so the token is not in the worker env |
| Consumer | worker mounts the Secret read-only at /var/run/secrets/repo-manager (defaultMode: 0440) and sets REPO_MANAGER_FORGEJO_TOKEN_FILE=/var/run/secrets/repo-manager/FORGEJO_READ_TOKEN (activity-core docs/rollout-owner-return-and-freshness-worker.md §3b, lines marked "only once 3c is resolved") |
| Rotation | every 180 days or owner change; Forgejo PATs have no server-side expiry |
| Front door | ops-warden activity-core-repo-manager-forgejo-read, follow-up after approval |
Open choice for the reviewer: either a dedicated ClusterSecretStore
openbao-activity-core-repo-manager-forgejo (CCR-2026-0031 pattern, below) or
granting the existing openbao-activity-core store role read on the new path.
The dedicated store keeps this high-risk org-wide read separate from the
worker's other secrets and is the default here.
Draft manifests (land only after metadata apply)
# CCR-2026-0034 (to confirm). Do not apply until approval and confirm-binding.
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: openbao-activity-core-repo-manager-forgejo
labels:
app.kubernetes.io/part-of: railiance-gitops
railiance-platform/component: external-secrets
app.kubernetes.io/name: activity-core
spec:
provider:
vault:
server: http://openbao.openbao.svc:8200
path: platform
version: v2
auth:
kubernetes:
mountPath: kubernetes
role: external-secrets-activity-core-repo-manager-forgejo
serviceAccountRef:
name: external-secrets
namespace: external-secrets
conditions:
- namespaces:
- activity-core
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: actcore-repo-manager-forgejo-read
namespace: activity-core
spec:
refreshInterval: 5m
secretStoreRef:
kind: ClusterSecretStore
name: openbao-activity-core-repo-manager-forgejo
target:
template:
metadata: {}
name: actcore-repo-manager-forgejo-read
creationPolicy: Owner
deletionPolicy: Retain
data:
- secretKey: FORGEJO_READ_TOKEN
remoteRef:
key: workloads/activity-core/repo-manager-forgejo-read
property: FORGEJO_READ_TOKEN
Attended sequence (after approval)
- Reviewers approve and confirm the binding with the CCR tooling
(
credential-change.py approve …,confirm-binding …). - Founder, in their own terminal: delegated metadata apply (policy + auth
role), then mint the PAT through
warden access forgejo-admin-api-token --exec, verify scope, private-repository read and denials, write the value to OpenBao from stdin and read it back for equality. A bootstrap script modelled onscripts/openbao-bootstrap-core-hub-source.shandscripts/provision-core-hub-forgejo-source.pyis still to be written; it is not part of this draft. - Commit the two manifests and let Argo sync; check presence only.
- activity-core adds the token env and mount lines from its rollout package §3b, syncs, and runs the memo 3 apply trials.
- Add the ops-warden catalog entry and move the CCR to verified/active with evidence.