Manual Approval Gate for Tekton Pipelines
TOC
Feature OverviewUse CasesPrerequisitesSteps1. Declare the approval step in a pipeline2. Monitor approval status3. Approve or rejectUser approvalsGroup approvals4. ExtendPipelineRun timeouts for long approvalsOperation ResultsTroubleshootingUser and group identifiersLearn MoreFeature Overview
Manual Approval Gate lets pipeline authors pause a PipelineRun until designated approvers review and approve the operation. Behind the scenes, the Operator-provided controller creates an ApprovalTask resource for every approval step, tracks approver responses, and writes the result back to the originating CustomRun.
Use Cases
- Enforcing human checkpoints before deploying to production or performing destructive maintenance.
- Implementing multi-person approval policies by combining individuals and groups with
numberOfApprovalsRequired. - Auditing who approved or rejected a change by querying
ApprovalTaskstatus fields or CLI output.
Prerequisites
- A cluster administrator has deployed
Manual Approval Gate. If not, refer to the deployment guide. - You can create or edit
Pipeline/PipelineRunobjects in the target namespace. - Approvers can patch
approvaltasks.openshift-pipelines.orgresources (typically viakubectl) in the target namespace. Platforms such asAlauda Container Platformgrant this capability by default; only customize RBAC if you have explicitly removed the built-in permissions.
Steps
1. Declare the approval step in a pipeline
When the pipeline reaches wait-for-approval, Tekton emits a CustomRun. The approval controller creates an ApprovalTask with your parameters and keeps the PipelineRun pending until quorum is met or a rejection occurs.
2. Monitor approval status
Important status fields:
status.state: overall gate state such aspending,approved, orrejected.status.approvalsRequired/status.approvalsReceived: quorum tracking (the received count appears only after at least one approver responds).status.approversResponse: per-user/group outcome plus messages, useful for auditing.
3. Approve or reject
User approvals
First, inspect the approvers list to determine the correct index:
To approve as a user:
To reject as a user:
Group approvals
When a group is configured as an approver, individual members of that group can submit their approval by adding their response to the users array under the group entry. Multiple group members can approve independently, and each approval counts toward the approvalsReceived total.
Initially, the group approver entry does not have a users field:
The first group member creates the users array and sets the group's input to approve:
Subsequent group members append to the existing users array and update the group's input:
To reject as a group member:
After these patches, check the group entry and status to see all members' responses:
In this example, both bob and carol from the release-managers group have approved. Each approval from a group member increments approvalsReceived separately, so two group member approvals count as two approvals toward the required total. The status.approversResponse shows detailed approval information including individual group members' responses.
Key points for group approvals:
- Each group member must perform two required operations: add their entry to the
usersarray AND set the group'sinput(eitherapproveorreject). Optionally, they can also set the group'smessage - The first group member creates the
usersarray using path/spec/approvers/<index>/userswith an array value - Subsequent members append to the array using path
/spec/approvers/<index>/users/-where-appends to the array end - Each user entry in the
usersarray contains onlynameandinputfields (nomessagefield within the user entry) - The group-level
messagefield is optional and shared; it will be overwritten by subsequent responses if they provide a new message - Each group member approval increments
approvalsReceivedindependently - Multiple members from the same group can approve, and each counts toward the required total
- The
status.approversResponsefield tracks detailed approval information including individual group members - Use
--as <username> --as-group <groupname>to identify as a group member when patching
The controller sets the corresponding CustomRun and PipelineRun to Succeeded or Failed accordingly: approvals accumulate until numberOfApprovalsRequired is satisfied, while any rejection immediately fails that section of the pipeline.
Tip: Use
--as <username>(required) and--as-group <group>when you need to approve as a specific identity. The validation webhook allows you to modify only the entry that matches that impersonated user and group. RBAC must grant you impersonation rights. For example,kubectl patch ... --as bob --as-group release-managersidentifies you as userbobacting within therelease-managersgroup.
4. Extend PipelineRun timeouts for long approvals
If an approval could take hours or days, configure both PipelineRun.spec.timeouts.pipeline and PipelineRun.spec.timeouts.tasks to exceed the approval window so the run does not terminate before approvers respond. A simple PipelineRun to exercise the approval gate looks like the following:
Ensure the approval task's timeout parameter is shorter than the pipeline timeout. Otherwise, the PipelineRun might expire first, leaving the approval unresolved.
Operation Results
kubectl get approvaltasks -o yamlshows each approval gate withstateand quorum-related fields (theapprovalsReceivedcolumn appears after someone responds).PipelineRunstatus reflects the approval outcome: when approved, downstream tasks resume; when rejected, the run fails with the reason propagated from theApprovalTask.- Dispatch logs or
kubectl get approvaltask -o yamloutput provide the approval history for auditing.
Troubleshooting
- Approval task never appears: Confirm the administrator-installed
ManualApprovalGateCR isREADY. Without the controller,CustomRunobjects remain pending. - Approvers lack permissions: Grant them
get,list,update, andpatchaccess toapprovaltasks.openshift-pipelines.orgin the relevant namespace. - Pipeline ended before approval finished: Set both
PipelineRun.spec.timeouts.pipelineandPipelineRun.spec.timeouts.tasksto cover the expected approval window, and ensure the approvaltimeoutis realistic. Otherwise the run may time out even if approvers have not responded. - Stuck in pending even after approvals: Check
status.approversResponsefor users who changed their vote or rejected. You may need to update the approver list and rerun the pipeline.
User and group identifiers
Manual Approval Gate relies on your platform's identity provider to match approver names. Always use the canonical identifiers exposed by the provider rather than UI display names. For example, on Alauda Container Platform:
Use the USERNAME column (such as admin) when adding user approvers.
Use the NAME column (such as g-v9mfs) when referencing group approvers (for example, group:g-v9mfs). Other platforms expose similar resources—consult the identity service documentation for the exact field names.