Skip to main content

GATE A WORKFLOW WITH MANUAL APPROVAL

This guide shows you how to hold a workflow at a human sign-off before it touches production: add a manual_approval gate, run the workflow until it suspends, review the pending gate out of band, then approve or reject and resume.

Use this when a run reaches a point that needs a person to confirm — a production rollout after staging is verified, a destructive migration, or any step whose blast radius warrants a second pair of eyes.

Prerequisites

  • swamp installed and on your PATH
  • An initialised repo (swamp repo init)
  • Familiarity with workflow definitions

Add a gate to the workflow

Place a manual_approval step between the work that prepares a change and the work that commits it. Make the downstream step depend on the gate so it cannot run until the gate is approved:

jobs:
  - name: rollout
    steps:
      - name: deploy-staging
        task:
          type: model_method
          modelType: command/shell
          modelName: staging-deploy
          methodName: execute
          inputs:
            run: echo "deployed to staging"
      - name: production-gate
        dependsOn:
          - step: deploy-staging
            condition:
              type: succeeded
        task:
          type: manual_approval
          prompt: "Staging verified. Approve production rollout?"
          timeout: 3600
      - name: deploy-production
        dependsOn:
          - step: production-gate
            condition:
              type: succeeded
        task:
          type: model_method
          modelType: command/shell
          modelName: production-deploy
          methodName: execute
          inputs:
            run: echo "deployed to production"

The prompt is what the approver sees. Set timeout (in seconds) when a stale approval should be refused — see Expire a stale gate.

Run the workflow until it suspends

Run the workflow. It executes up to the gate and then suspends:

swamp workflow run gated-deploy

You will see output like:

workflow·run·gated-deploy·rollout·production-gate Awaiting manual approval: "Staging verified. Approve production rollout?"
workflow·run·gated-deploy Workflow suspended — awaiting approval on step "production-gate"

  swamp workflow approve "gated-deploy" "production-gate"
  swamp workflow reject  "gated-deploy" "production-gate"

After approval: swamp workflow resume "gated-deploy"

The run now holds: the staging step is succeeded, the gate is waiting_approval, and the production step stays pending.

Verify out of band, then decide

Do whatever the gate exists to confirm — check staging metrics, run smoke tests, get a colleague's eyes on it. The run waits while you do.

To see every gate currently awaiting a decision across all workflows:

swamp workflow approvals
workflow·approvals "gated-deploy" / "production-gate" — "Staging verified. Approve production rollout?"
  swamp workflow approve "gated-deploy" "production-gate"
  swamp workflow reject  "gated-deploy" "production-gate"
  After approval: swamp workflow resume "gated-deploy"

A gate only appears here while it is still within its approval window. Once a gate's timeout lapses it drops out of this listing, so an empty list after the deadline is expected — the gate can no longer be approved.

If the change is good, approve the gate. Pass --reason to record why on the run's audit trail:

swamp workflow approve gated-deploy production-gate --reason "Staging metrics nominal"

If the change is not safe to proceed, reject it. A rejection marks the whole run failed:

swamp workflow reject gated-deploy production-gate --reason "Error budget exhausted"
workflow·reject Rejected step "production-gate" in workflow "gated-deploy"
workflow·reject Workflow run marked as failed.

Resume after approval

Approving records the decision but does not run the remaining steps. Resume the run to execute everything after the gate:

swamp workflow resume gated-deploy

Resume skips the steps that already completed and picks up at the gate's dependents:

workflow·run·gated-deploy·rollout·deploy-production Step started
model·method·run·production-deploy·execute deployed to production
workflow·run·gated-deploy Workflow "succeeded"

If you resume before approving, the run refuses and names the step to approve first:

Step "production-gate" is still awaiting approval. Run "swamp workflow approve gated-deploy production-gate" first.

Hand off approval to someone else

The person who runs a workflow and the person who approves its gate need not be the same. Anyone with repo access can list pending gates with swamp workflow approvals and approve or reject them; the identity that decides is recorded as decidedBy on the gate. After a colleague approves, you (or they) run swamp workflow resume to continue.

Expire a stale gate

Set timeout (seconds) on the gate so an approval that arrives too late is refused rather than silently shipping a change nobody is still watching:

task:
  type: manual_approval
  prompt: "Staging verified. Approve production rollout?"
  timeout: 2

Once the window elapses, approving fails and the gate stays unapproved:

Error: 'Approval timed out: step "production-gate" has been waiting 5s (timeout: 2s)'

An expired gate also drops out of swamp workflow approvals, so once the deadline passes that listing comes back empty — that is expected, not a sign the run is lost. Re-run the workflow to open a fresh approval window.

Reference

For the full field list, status values, and the approvalDecision record, see the workflows reference. For how suspend and resume work under the hood, see Understanding Workflow Suspension.