Approval gates
Crow supports two distinct approval mechanisms:
- Pipeline-level approval — gates an entire pipeline before any workflow runs. Configured per repo via Approval requirements.
- Workflow-level approval gates — gates a single workflow in the middle of a pipeline. Configured per workflow in
.crow.yml.
This page is about the second.
See approval in the workflow syntax reference for the schema.
Behaviour
Section titled “Behaviour”- The pipeline starts and runs all upstream workflows normally.
- When a gated workflow’s upstream deps all finish successfully, the workflow goes to the blocked state. No agent slot is held while it waits.
- An authorized user approves or declines via the UI or CLI. If neither happens, the timeout sweeper auto-declines after the gate’s configured timeout.
- On approve, the gated workflow runs.
- On decline (or timeout), the gated workflow is marked declined, all of its downstream workflows are marked skipped, and the pipeline finishes with a top-level declined status.
While a workflow waits at the gate, the overall pipeline status is blocked, not success — the pipeline is not done.
After a decline or timeout it rolls up to declined.
The status precedence is killed > declined > failure > blocked > running > success, so a single blocked workflow surfaces as a blocked pipeline even when every other workflow has finished.
Gating a specific step
Section titled “Gating a specific step”Crow gates at the workflow level, not the step level.
You cannot put approval: on an individual step — the schema only accepts it at the top level of a workflow.
A workflow is all-or-nothing once it starts; the gate sits in front of a workflow’s steps, never between them.
To gate a single step, split it into its own workflow.
Put the free-running steps in one workflow, and put the step(s) you want behind the gate in a second workflow that depends_on the first and carries the approval block.
.crow/01-ci.yaml runs unguarded:
.crow/02-deploy.yaml waits for 01-ci and gates the deploy behind approval:
For a checkpoint in the middle of a sequence (approve after step A, before step B), split again into more workflows chained with depends_on.
Each gate is a per-workflow boundary, so every extra checkpoint is one more workflow.
Approving via UI
Section titled “Approving via UI”Open the pipeline view. Gated workflows show an “Approval required” panel with Approve and Decline buttons. Add an optional reason for the audit trail.
The navbar pending-approvals indicator also surfaces workflow gates you can approve, across all your repos.
Approving via CLI
Section titled “Approving via CLI”See pipeline workflow in the CLI reference.
Server configuration
Section titled “Server configuration”Three environment variables control gate behaviour:
CROW_APPROVAL_GATE_TIMEOUT_DEFAULT(default24h) — applied when YAML omitstimeout.CROW_APPROVAL_GATE_TIMEOUT_MAX(default168h, 7d) — hard cap. YAML with a longer timeout fails lint.CROW_APPROVAL_GATE_SWEEP_INTERVAL(default30s, minimum5s) — how often the timeout sweeper runs.
See Approval gates in the server configuration reference for details.
Differences from pipeline-level approval
Section titled “Differences from pipeline-level approval”| Pipeline-level | Workflow-level | |
|---|---|---|
| Configured in | Repo settings | .crow.yml per workflow |
| Triggered by | Forge events (e.g. PR from fork) | approval.required: true |
| Approvers | Anyone with push perm | Configurable list + push perm fallback |
| Granularity | Entire pipeline before anything runs | Single workflow mid-pipeline |