Skip to main content
Amends 0012: the workflow rules below apply to every workflow in the repository.

Context

GitHub Actions workflows run with broad default permissions, and a pull request from a fork can run them. The owner answered CI11–CI13 on 2026-10-20 (mem L415–418). The bot credential that opens and merges pull requests also needs a home that is not a repository secret.

Decision

  1. Least privilege (CI11). Every workflow sets permissions: {} at the top and grants each job only what it needs. zizmor checks workflows. The setup action is mise-action.
  2. Bot credentials (CI12). The bot App ID and private key move to Infisical /ci, read through OIDC. Until that move lands, they are release-environment secrets, never repository-wide secrets.
  3. Outside contributors (CI13). Every run for an outside contributor waits for approval. pull_request_target never runs with a checkout of the pull request.

Consequences

  • A workflow that grants more than it needs fails zizmor review.
  • A fork’s pull request cannot read a secret or run with write access.
  • The bot identity is the one the Quality Gate and pr:merge use (ADR 0119); a human’s personal token is never used for merges.

Enforcement

planned — zizmor in the gate for .github/workflows/*; the outside-contributor approval is a repository setting that the runbook records. The runbooks/secrets.mdx page is updated with the bot-credential move (final pass).

Alternatives

  • Repository-wide bot secret: rejected by CI12.
  • pull_request_target with a PR checkout: rejected by CI13.

Supersedes and sources

Supersedes: none. Amends: 0012. Sources: owner answers CI11–CI13 (stackra-decisions-2026-10-19.md L415–418, 2026-10-20). Closes gaps B25 and B26.