Manual Approval Gate for Tekton PipelinesManual 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.
numberOfApprovalsRequired.ApprovalTask status fields or CLI output.Manual Approval Gate. If not, refer to the deployment guide.Pipeline/PipelineRun objects in the target namespace.approvaltasks.openshift-pipelines.org resources (typically via kubectl) in the target namespace. Platforms such as Alauda Container Platform grant this capability by default; only customize RBAC if you have explicitly removed the built-in permissions.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.
Important status fields:
status.state: overall gate state such as pending, approved, or rejected.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.First, inspect the approvers list to determine the correct index:
To approve as a user:
To reject as a user:
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:
users array AND set the group's input (either approve or reject). Optionally, they can also set the group's messageusers array using path /spec/approvers/<index>/users with an array value/spec/approvers/<index>/users/- where - appends to the array endusers array contains only name and input fields (no message field within the user entry)message field is optional and shared; it will be overwritten by subsequent responses if they provide a new messageapprovalsReceived independentlystatus.approversResponse field tracks detailed approval information including individual group members--as <username> --as-group <groupname> to identify as a group member when patchingThe 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.
PipelineRun timeouts for long approvalsIf 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.
kubectl get approvaltasks -o yaml shows each approval gate with state and quorum-related fields (the approvalsReceived column appears after someone responds).PipelineRun status reflects the approval outcome: when approved, downstream tasks resume; when rejected, the run fails with the reason propagated from the ApprovalTask.kubectl get approvaltask -o yaml output provide the approval history for auditing.ManualApprovalGate CR is READY. Without the controller, CustomRun objects remain pending.get, list, update, and patch access to approvaltasks.openshift-pipelines.org in the relevant namespace.PipelineRun.spec.timeouts.pipeline and PipelineRun.spec.timeouts.tasks to cover the expected approval window, and ensure the approval timeout is realistic. Otherwise the run may time out even if approvers have not responded.status.approversResponse for users who changed their vote or rejected. You may need to update the approver list and rerun the pipeline.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.