fix(ci): build bot fetches the forge-ci token via the ci-runner AppRole #196

Merged
peterswimm merged 1 commit from fix/build-bot-vault-token into main 2026-10-08 01:53:11 +00:00
Owner

Scope

The build bot's first live run (#195, run 936) failed at checkout with Input required and not supplied: token, because the UDG_BUILD_BOT_TOKEN secret was never created. This PR drops that
secret. The bot now fetches the forge-ci Forgejo token at run time from OpenBao
(secret/forge/forgejo/ci), using the org's existing ci-runner AppRole (CI_VAULT_ROLE_ID,
CI_VAULT_SECRET_ID, CI_VAULT_ADDR). That's the same path forge-ops auto-merge and Renovate
use, so no new standing secret is needed.

Per-job containers can't reach a fixed bridge IP or vault.forge. The step therefore tries
CI_VAULT_ADDR, then vault.forge, then the default gateway from /proc/net/route. That logic is
ported from forge-ops ci-shared and written in stdlib Python, because the slim image has no
curl or jq. The token is masked before it reaches the step output.

Trade-off: forge-ci is the org-wide CI identity, not a token scoped to this repo. We accept that
to avoid managing a second secret.

Testing

  • test_workflow_invariants.py: 62 passed. yamllint --strict .forgejo/workflows/: clean.
  • The discovery code, run in python:3.12-slim with an unreachable CI_VAULT_ADDR, reads the
    gateway from /proc/net/route and stops with ::error::OpenBao not reachable…. That checks the
    code fails cleanly when nothing is reachable.
  • The real AppRole login only works on the forge runner. After merge, I'll re-label #195 to run it
    live.

Impact Statement

  • Existing features: the build bot can now authenticate. Nothing else changes.
  • Public APIs / contracts: none.
  • Schemas: none.
  • Data / artifacts: none.
  • Integrations: OpenBao through the existing ci-runner AppRole. UDG_BUILD_BOT_TOKEN is no longer
    needed.
  • Mappings: none.
  • Backward compatibility: no expected impact.

Docs

The workflow's header comment records the credential path and the trade-off.

## Scope The build bot's first live run (#195, run 936) failed at checkout with `Input required and not supplied: token`, because the `UDG_BUILD_BOT_TOKEN` secret was never created. This PR drops that secret. The bot now fetches the **forge-ci** Forgejo token at run time from OpenBao (`secret/forge/forgejo/ci`), using the org's existing **ci-runner AppRole** (`CI_VAULT_ROLE_ID`, `CI_VAULT_SECRET_ID`, `CI_VAULT_ADDR`). That's the same path forge-ops `auto-merge` and Renovate use, so no new standing secret is needed. Per-job containers can't reach a fixed bridge IP or `vault.forge`. The step therefore tries `CI_VAULT_ADDR`, then `vault.forge`, then the default gateway from `/proc/net/route`. That logic is ported from forge-ops `ci-shared` and written in stdlib Python, because the slim image has no `curl` or `jq`. The token is masked before it reaches the step output. **Trade-off:** forge-ci is the org-wide CI identity, not a token scoped to this repo. We accept that to avoid managing a second secret. ## Testing - `test_workflow_invariants.py`: 62 passed. `yamllint --strict .forgejo/workflows/`: clean. - The discovery code, run in `python:3.12-slim` with an unreachable `CI_VAULT_ADDR`, reads the gateway from `/proc/net/route` and stops with `::error::OpenBao not reachable…`. That checks the code fails cleanly when nothing is reachable. - The real AppRole login only works on the forge runner. After merge, I'll re-label #195 to run it live. ## Impact Statement - Existing features: the build bot can now authenticate. Nothing else changes. - Public APIs / contracts: none. - Schemas: none. - Data / artifacts: none. - Integrations: OpenBao through the existing ci-runner AppRole. `UDG_BUILD_BOT_TOKEN` is no longer needed. - Mappings: none. - Backward compatibility: no expected impact. ## Docs The workflow's header comment records the credential path and the trade-off.
fix(ci): build bot fetches the forge-ci token via the ci-runner AppRole
Some checks failed
PR policy check / policy-gate (pull_request) Successful in 0s
Test Generator / lint-workflows (pull_request) Successful in 21s
Test Generator / lint-prose (pull_request) Successful in 21s
Security Scans / Gitleaks secret scan (pull_request) Successful in 29s
Security Scans / Trivy filesystem scan (pull_request) Failing after 31s
UDG dist drift gate / dist/ matches dtcg + udg sources (pull_request) Successful in 13s
Copy coverage / Design copy reaching rendered HTML (pull_request) Successful in 26s
Block Validation / validate (pull_request) Successful in 51s
Test Generator / test (pull_request) Successful in 3m24s
6592d6bc78
The bot's first live run (#195, run 936) failed at checkout: the
UDG_BUILD_BOT_TOKEN secret it read was never created. Use the org's
existing ci-runner AppRole instead (CI_VAULT_ROLE_ID / CI_VAULT_SECRET_ID /
CI_VAULT_ADDR) to read the forge-ci Forgejo token at
secret/forge/forgejo/ci, the same path forge-ops auto-merge and Renovate
use, so no new standing secret is needed.

The job runs in a container, which can't reach a fixed bridge IP or
vault.forge, so the step tries CI_VAULT_ADDR, vault.forge, then the default
gateway read from /proc/net/route (ported from forge-ops ci-shared, in
stdlib Python because the slim image has no curl or jq). Token is masked
before it is written to the step output.

Trade-off: forge-ci is org-wide, not scoped to this repo.
peterswimm deleted branch fix/build-bot-vault-token 2026-10-08 01:53:11 +00:00
Sign in to join this conversation.
No description provided.