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.