Skip to main content

CI workflow grants

A workflow actor — the token minted by the GitHub Actions OIDC exchange — is bound to exactly one (workspace, project). Inside that bound scope it holds a small, deliberate grant set; outside it, nothing. This page is the complete list.

What CI can do

GrantSurfaceBound to
Environment listGET …/projects/{projectId}/environmentsExactly the token-bound project
Secret metadata listGET …/config/secrets at project and environment scopeRungs under the bound project
Run-lease secret resolvePOST …/state/runs/{runId}/secrets/resolvesecret.value.use within bound scope, plus a live lease
Job output secret publishPOST …/state/runs/{runUlid}/output-secretsstate.object.write within bound scope, plus a live lease
Terraform state read/writetfstate pathsstate.object.read/.write, plus the repo allow-list and an active project

Plus the state-plane run/object/catalog actions already documented on the state API reference — all within the bound workspace + project.

Environment list

The grant predicate is exact: the actor's subjectType is workflow, its bound org equals the route's org, and its bound project equals the route's project. Nothing else on the environments surface is granted — no create, no get-by-id, no archive, no restore, and no other project's list. CI can enumerate the deploy targets of the repo it runs for, and that is all.

Secret metadata list

Workflow actors may list secret metadata (never values) at the project and environment rungs under their bound project — this is what lets a runner resolve a key to its id before a lease-bound resolve. The org-wide ?scope=all listing is explicitly excluded: org-rung access is never granted to CI.

What CI cannot do

  • Write secrets through the config API. Create, rotate, and revoke on …/config/secrets are not granted to workflow actors. The only CI write path for secrets is the job output publish, which is lease-bound and server-scoped. (An earlier grant that allowed CI writes through the config API was reverted.)
  • Touch the org rung. Every workflow grant requires a non-null bound projectId — a workflow token never authorizes an organization-scoped read or write.
  • Reach another project. The bound project is in the token; a route naming any other project denies (as a resource-hiding 404).
tip

This grant set is why the zero-secret CI story holds: a leaked workflow token expires in ~15 minutes, touches one project, can read only metadata and lease-gated values, and can write only through channels where the server derives the scope. See CLI & CI authentication for how the token is minted.