Skip to main content

wait-for-approval

info

This promotion step is only available in Kargo on the Akuity Platform, versions v1.12.0 and above.

The wait-for-approval step pauses a promotion and waits for human approval before it continues. The promotion stays in a running state, surfacing an approval prompt in the Kargo UI, until enough distinct users approve or any eligible user rejects. A rejection fails the step (and the promotion). Both the approvals and the rejection are recorded, so the full decision trail is available to later steps.

warning

Do not reference secrets in this step's config. Kargo renders the config (evaluating expressions, including secret()) before the step runs, and the rendered result is stored on the step's record and shown in the Kargo UI. Any secret pulled into the config this way may be exposed to anyone who can view the Promotion.

Approvers

The approvers field lists the rules that decide who may approve or reject. The rules are ORed: a caller matching any rule may respond. When approvers is omitted, any authenticated user who can see the Promotion may respond.

Each rule matches either an OIDC claim or a Kargo role:

FieldTypeDescription
claimstringThe name of an OIDC claim to match (e.g. groups, email). Must be paired with value.
valuestringThe claim value to match. For list-valued claims (e.g. groups), the rule matches if the list contains this value.
rolestringThe name of a Kargo role (a project ServiceAccount) the caller must be mapped to.
requiredbooleanWhen true, the step cannot succeed until at least one approval comes from a user matching this rule. Defaults to false.

A rule sets either claim and value, or role — not both.

Configuration

NameTypeRequiredDescription
approvers[]objectNRules identifying who may approve or reject. See Approvers. When empty, any authenticated user who can see the Promotion may respond.
minApprovalsintegerNThe number of distinct users that must approve before the step succeeds. Defaults to 1.
pollIntervalstringNHow often to re-check for responses as a fallback (the step also wakes immediately when a response arrives). A Go duration string. Defaults to 30s.

Output

NameTypeDescription
responses[]objectEvery response received, in chronological order. Includes the approvals and, on rejection, the rejection.

Each entry in responses has the following fields:

FieldTypeDescription
userstringThe identity of the responder.
actionstringThe action taken: approve or reject.
timestringWhen the response was recorded, as an RFC 3339 timestamp.
messagestringAn optional free-text message the responder left. Omitted when none was provided.

Example

Single Approval

Pause until any authenticated user who can see the Promotion approves:

steps:
- uses: wait-for-approval
as: approve

Quorum With a Required Approver

Require two distinct approvals, at least one of which must come from a member of the platform-leads group, and let the project's release-manager role approve as well:

steps:
- uses: wait-for-approval
as: approve
config:
minApprovals: 2
approvers:
- claim: groups
value: platform-leads
required: true
- role: release-manager

Recording the Decision

The responses output carries the full trail, so a later step can record who approved (or why a promotion was rejected):

steps:
- uses: gh-create-issue
as: ticket
config:
repoURL: https://github.com/myorg/myrepo
title: "Promote to ${{ ctx.stage }}"

- uses: wait-for-approval
as: approve
config:
minApprovals: 1

- uses: gh-issue-add-comment
config:
repoURL: https://github.com/myorg/myrepo
issueNumber: ${{ outputs.ticket.number }}
body: |
Approved by:
${{ join(map(outputs.approve.responses, "- " + .user + (.message == nil ? "" : ": " + .message)), "\n") }}