KSE-0182 Amendment A: workload identity plane and agenix -> OpenBao cutover #39
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
key-store/key.store!39
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "kse/0182-amendment-a-workload-identity"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Founder direction 2026-08-16: move secrets into OpenBao, WIF for everything, deployed with OpenTofu. This records the decisions and a phased plan as Amendment A of KSE-0182 (plus a scope note on KSE-0174). Proposal only — no runtime changes.
What it fixes in the record
mainand enabled on the forge but has never come up (activating (auto-restart-queued)since 2026-06-14). Reproduced first blocker: Postgres socket0770 postgres:postgresvsDynamicUser=openbaowith noSupplementaryGroups=postgres; behind that, thegcpckmsseal has no Google credential — the same gap that keeps the Garage GCS archive leg off (PR #36).infra/openbao's jwt auth), one client-credentials provider per workload class.google-wif-credentials.service→/run/google-wif/credentials.json,external_account) serves the OpenBao seal, the rclone GCS leg (env_auth), and cloud-tofu.LoadCredentialon the forge;jwt/AppRole login in CI;decrypt-secrets→openbao-secrets; then delete theAGE_FORGE_SSH_KEYActions secret used by 22 workflows).infra/identity) and auth roles/policies/mounts (infra/openbao); never secret values.Decisions to confirm or change on review
🤖 Generated with Claude Code
Revision pushed (2nd commit) — correction + design change.
The first draft claimed Forgejo 15.0.2 cannot mint job-scoped OIDC tokens, "verified in the binary". That was wrong: the grep ran against the 1 KB nix wrapper at
bin/forgejo, notbin/.forgejo-wrapped. Against the real binary, the v15.0 source and the live instance, the feature is already live on the forge: issuerhttps://git.key.store/api/actions, discovery/JWKS at/api/actions/.well-known/{openid-configuration,keys}(200 today), RS256,sub = repo:<owner/repo>:ref:<ref>(or:pull_request), claimsrepository/ref/workflow_ref/event_name/actor/run_id/…, gated per job bypermissions: id-token: write; forgejo-runner 12.10.2 (deployed) exposesACTIONS_ID_TOKEN_REQUEST_URL/TOKEN. Forgejo 16 hardens it (#12030, #11194, #12275) — upgrade is a founder call since it leaves the 15 LTS line.Design now: Forgejo issues identity for every Actions job on every runner class (Google/Azure WIF providers + an OpenBao
jwtauth backendforgejo-actionsbound onrepository/ref/workflow_ref; PR runs get no role; no AppRole or runner-side credential for CI). Authentik issues for the forge host (seal, mirrors), KSE-0181 residencies, and humans. Phase 1 adds Forgejo issuer hygiene (explicit signing-key path + backup, 600 s TTL) and makescloud-tofu.ymlthe first job-token consumer.Correction: the first draft said Forgejo 15.0.2 cannot mint job-scoped OIDC tokens "verified in the binary". That grep ran against the 1 KB nix wrapper at bin/forgejo, not bin/.forgejo-wrapped. Against the real binary, the v15.0 source (routers/api/actions/{oidc,id_token}.go) and the live instance: - issuer https://git.key.store/api/actions, discovery + JWKS at /api/actions/.well-known/{openid-configuration,keys} (200 today), RS256, TTL [actions] ID_TOKEN_EXPIRATION_TIME (3600 s default), key auto-generated at <AppDataPath>/actions_id_token/private.pem - job token via /_apis/pipelines/workflows/{run_id}/idtoken?audience=... with the runtime token when the job has permissions: id-token: write; forgejo-runner 12.10.2 (deployed) exposes ACTIONS_ID_TOKEN_REQUEST_* - sub = repo:<owner/repo>:ref:<ref> | ...:pull_request; claims repository, ref, workflow_ref, event_name, actor, run_id, sha, ... - Forgejo 16 hardens it (#12030 authorisation, #11194 key config, #12275 JWKS caching); upgrade is a founder call (leaves the 15 LTS line). Design change: two issuers. Forgejo issues identity for every Actions job on every runner class (Google/Azure WIF providers + an OpenBao jwt auth backend "forgejo-actions" bound on repository/ref/workflow_ref; PR runs get no role). Authentik issues for the forge host (seal, mirrors), KSE-0181 residencies, and humans. No AppRole/runner-side credential for CI. Phase 1 adds Forgejo issuer hygiene (explicit signing-key path + backup, 600 s TTL) and cloud-tofu as the first job-token consumer. Non-goal "patching Forgejo" removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>80e10221b4to898834aae5