diff --git a/credential-change-requests/CCR-2026-0031-core-hub-forgejo-source-read.yaml b/credential-change-requests/CCR-2026-0031-core-hub-forgejo-source-read.yaml index 92c5d5c..c794465 100644 --- a/credential-change-requests/CCR-2026-0031-core-hub-forgejo-source-read.yaml +++ b/credential-change-requests/CCR-2026-0031-core-hub-forgejo-source-read.yaml @@ -3,23 +3,36 @@ kind: credential-change-request schema_version: 1 request_type: workload-kv-read title: Core Hub repo-manager publisher Forgejo private-source read token lane -status: proposed +status: approved created: '2026-10-03' updated: '2026-10-03' requester: agent: claude (rapp-core-hub repo agent, dispatched by the-custodian under CUST-WP-0075) reason: RAPPCOREHUB-WP-0003-T04. The repo-manager publisher in namespace core-hub reads the 123-entry repository registry from Forgejo anonymously; nine private - sources return HTTP 404, so admission cannot reach 123 accepted / 0 errors. - The Forgejo admin PAT, any personal SSH key or PAT, and the policy-nexus-source - token (CCR-2026-0014) are prohibited for this workload. A dedicated identity - with read:repository only is required. + sources return HTTP 404, so admission cannot reach 123 accepted / 0 errors. The + Forgejo admin PAT, any personal SSH key or PAT, and the policy-nexus-source token + (CCR-2026-0014) are prohibited for this workload. A dedicated identity with read:repository + only is required. review: required: true required_approvers: - platform-operator - core-hub-owner - comments: [] + comments: + - at: '2026-10-03T06:32:38+00:00' + reviewer: bernd + decision: binding_confirmed + comment: 'Founder confirmed 2026-10-03 in chat: ''APPROVE CCR-2026-0031 and confirm + binding''. Kubernetes role binds external-secrets/external-secrets, same as + confirmed CCR-2026-0013.' + - at: '2026-10-03T06:32:45+00:00' + reviewer: bernd + decision: approved + comment: 'Founder approved 2026-10-03 in chat: ''APPROVE CCR-2026-0031 and confirm + binding''. Approves the dedicated core-hub-source Forgejo user with a read:repository-only + PAT, OpenBao path platform/workloads/core-hub/forgejo-source-read, ESO delivery + only into namespace core-hub. Provisioning remains a separate attended run.' target: domain: infotech tenant: core-hub @@ -27,8 +40,8 @@ target: rapp: rapp-core-hub environment: production purpose: Hold a dedicated Forgejo PAT scoped exactly read:repository and project - it through External Secrets into namespace core-hub as the Secret that the - rapp-core-hub publisher mounts read-only at /var/run/secrets/repo-manager/forgejo/token. + it through External Secrets into namespace core-hub as the Secret that the rapp-core-hub + publisher mounts read-only at /var/run/secrets/repo-manager/forgejo/token. openbao: mount: platform kv_path: platform/workloads/core-hub/forgejo-source-read @@ -49,14 +62,15 @@ openbao: - external-secrets service_account_namespaces: - external-secrets - bound_claims_confirmed: false + bound_claims_confirmed: true policies: - workload-kv-read-core-hub-forgejo-source ttl: 15m access_frontdoor: type: ops-warden catalog_id: core-hub-forgejo-source-read - selector: core hub repo-manager publisher Forgejo private source repository read token + selector: core hub repo-manager publisher Forgejo private source repository read + token readiness: pending-review resolvable: false delivery: @@ -68,29 +82,29 @@ delivery: (remoteRef workloads/core-hub/forgejo-source-read property FORGEJO_SOURCE_TOKEN), explicit empty target metadata template, creationPolicy Owner, deletionPolicy Retain. rapp-core-hub then sets publisher.existingSecret to repo-manager-forgejo-source - with tokenKey token. Both manifests are drafted in this CCR only and land in - argocd/platform-addons/openbao-secretstore after approval and metadata apply. + with tokenKey token. Both manifests are drafted in this CCR only and land in argocd/platform-addons/openbao-secretstore + after approval and metadata apply. forgejo_identity: core-hub-source forgejo_team: core-hub-source-readers - forgejo_team_contract: Restricted, non-admin, private - service user (random unrecorded password) in org coulomb; team permission read, includes_all_repositories - true, can_create_org_repo false, repo.code read, every non-code unit none. PAT - name prefix core-hub-source-read-, scope exactly read:repository. + forgejo_team_contract: Restricted, non-admin, private service user (random unrecorded + password) in org coulomb; team permission read, includes_all_repositories true, + can_create_org_repo false, repo.code read, every non-code unit none. PAT name + prefix core-hub-source-read-, scope exactly read:repository. repositories: All repositories of Forgejo org coulomb (the registry's 123 entries - are all coulomb/*). Per-repository team membership was rejected because the - registry changes weekly and each addition would need a new attended session. + are all coulomb/*). Per-repository team membership was rejected because the registry + changes weekly and each addition would need a new attended session. naming_basis: Follows the CCR-2026-0014 precedent (-source user, -source-readers - team). repo-manager publishes no service-user naming canon; its outstanding - identity-canon correction is a registry/Forgejo identity mismatch for one repository - and does not constrain this name. + team). repo-manager publishes no service-user naming canon; its outstanding identity-canon + correction is a registry/Forgejo identity mismatch for one repository and does + not constrain this name. provisioning_script: scripts/provision-core-hub-forgejo-source.py (silent, idempotent; admin token reaches it only through warden access forgejo-admin-api-token --exec) risk: classification: high notes: - - Read-only at Forgejo, but disclosure grants estate-wide private source read - for org coulomb. No package, repository-write, organization-admin, user-write, - Actions, cluster, or deployment authority. + - Read-only at Forgejo, but disclosure grants estate-wide private source read for + org coulomb. No package, repository-write, organization-admin, user-write, Actions, + cluster, or deployment authority. - Distinct from CCR-2026-0014; the policy-nexus-source identity and its token are never reused, so revoking either lane leaves the other intact. - The publisher calls the in-cluster Forgejo service over plain HTTP; the token @@ -105,19 +119,19 @@ verification: - The minted token metadata reports exactly read:repository; it resolves a branch and fetches one archive of a private coulomb repository, checked without printing the value. - - ExternalSecret core-hub/repo-manager-forgejo-source reports Ready and the - Secret exists (checked only with the safe secret_annotation_maintenance helper, - never by reading values). - - make verify-publisher in rapp-core-hub reports 123 accepted / 0 errors once - the separate identity-canon registry correction has shipped. + - ExternalSecret core-hub/repo-manager-forgejo-source reports Ready and the Secret + exists (checked only with the safe secret_annotation_maintenance helper, never + by reading values). + - make verify-publisher in rapp-core-hub reports 123 accepted / 0 errors once the + separate identity-canon registry correction has shipped. negative: - - The PAT cannot create, update, or delete repository content, write packages, - or read Actions secrets; /admin/users is denied. + - The PAT cannot create, update, or delete repository content, write packages, or + read Actions secrets; /admin/users is denied. - The effective permission of core-hub-source on a probe repository is read. - The external-secrets role cannot read platform/workloads/policy-nexus/forgejo-source-read or any sibling path; a default OpenBao identity cannot read this path. - - Removing the Secret makes publisher private-source reads fail with 404 again - (fail closed), not fall back to another credential. + - Removing the Secret makes publisher private-source reads fail with 404 again (fail + closed), not fall back to another credential. activation_conditions: - Platform operator and Core Hub owner approve this CCR. - Kubernetes auth role binding for the external-secrets service account is confirmed