Gatekeeper - Manual Approval Gates
Gatekeeper allows you to create manual approval gates in your Terrateam workflows, enabling authorized users to override failures from security scans, policy checks, or custom validations. This is particularly useful when you need human judgment to determine if certain violations are acceptable given the context.
Understanding Gatekeeper
Section titled “Understanding Gatekeeper”When a gated workflow step fails (such as a security scan detecting issues or a policy check finding violations), instead of failing the plan, Gatekeeper:
- Records a gate for the directory and workspace the step ran in
- Lets the rest of the plan workflow continue
- Blocks the apply of that directory and workspace until the gate is approved
This allows teams to maintain strict automated checks while providing flexibility for legitimate exceptions.
Gates can be associated with a token, which requires users to explicitly approve every gate that their approval has been requested on, using a pull request comment.
Gates that are not associated with a token require all requested approvers to approve the pull request in the VCS provider before changes can be applied.
How Gatekeeper Works
Section titled “How Gatekeeper Works”-
A gated step fails: A workflow step configured with a gate encounters a failure condition during the plan.
-
Gate recorded: Terrateam records the gate for the directory and workspace. The failure of the step is ignored and the plan continues.
-
Apply is blocked: When an apply is attempted, Terrateam checks every gate for the directories and workspaces being applied. If any gate is not satisfied, Terrateam posts a comment that lists:
- The gate token or name
- The directory and workspace
- Who can approve the gate and how many approvals are still required
-
Authorized user reviews: Team members review the failure and determine if it’s acceptable.
-
Approval granted: An authorized user approves the gate. For gates with a token, comment:
terrateam gate approve <token>Multiple tokens can be approved in one comment:
terrateam gate approve <token1> <token2>.For gates without a token, approve the pull request.
-
Apply continues: Once every gate is satisfied, the apply proceeds.
Configuring Gates
Section titled “Configuring Gates”There are three ways to create gates:
- The
gatekey on thecheckov,conftest, andopaworkflow step types. The gate is created when the step fails. - The
on_errorkey on therunworkflow step and hook type, with an entry oftype: gate. The gate is created when the command exits non-zero. - The
gatesworkflow step and hook type, which runs a command that outputs the gates to create. Use this to compute gates dynamically, for example based on the plan output.
Gate Configuration Options
Section titled “Gate Configuration Options”These keys are accepted in the gate object, in an on_error entry of type: gate, and in each gate output by a gates step.
| Key | Type | Description |
|---|---|---|
token |
String | A unique identifier for this gate. Gates with a token are approved with terrateam gate approve <token>. Gates without a token are approved by approving the pull request. |
name |
String | A name to give the gate. This is useful for identifying why the gate was created when a token is not used. |
all_of |
List | List of users, teams, or roles that must ALL approve the gate. |
any_of |
List | List of users, teams, or roles from which any_of_count approvals are required. |
any_of_count |
Integer | Number of approvals required from the any_of list. Default is 0, which means no approval from the any_of list is required. Set it to 1 or more when using any_of. |
Entries in all_of and any_of use the same syntax as access control: user:<username>, team:<team-slug>, role:<repository-role>, or *.
A gate is satisfied when every entry in all_of has approved and at least any_of_count distinct approvers matching any_of have approved.
Authorization Patterns
Section titled “Authorization Patterns”Gatekeeper supports flexible authorization patterns:
Single Approver:
gate: token: "security-override" any_of: ["user:security-lead"] any_of_count: 1Any Team Member:
gate: token: "platform-approval" any_of: ["team:platform", "team:sre"] any_of_count: 1Multiple Required Approvers:
gate: token: "critical-override" all_of: ["team:security", "team:compliance"]N-of-M Approvals:
gate: token: "cost-approval" any_of: ["user:cfo", "user:cto", "user:eng-director", "user:finance-lead"] any_of_count: 2Gating a run step
Section titled “Gating a run step”The run step does not accept a gate key. Use on_error instead. When a run step has a gate in on_error, ignore_errors defaults to true for that step so the failed command does not fail the plan.
workflows: - tag_query: "" plan: - type: init - type: plan - type: run cmd: ['./scripts/cost-check.sh'] on_error: - type: gate token: "cost-threshold" any_of: ["team:finance", "user:budget-owner"] any_of_count: 1Creating gates dynamically with the gates step
Section titled “Creating gates dynamically with the gates step”The gates step runs a command and reads the gates to create from its standard output. The command must print a JSON object with a gates list. Each gate accepts the keys above plus add_reviewers (default true), which requests a review on the pull request from the user: and team: entries in all_of and any_of. The step always counts as failed so that its gates are recorded; it never fails the plan.
workflows: - tag_query: "" plan: - type: init - type: plan - type: gates cmd: ['./scripts/compute-gates.sh']Example output of ./scripts/compute-gates.sh:
{ "gates": [ { "token": "database-change", "name": "Database schema change", "any_of": ["team:dba"], "any_of_count": 1, "add_reviewers": true } ]}The gates step accepts these keys:
| Key | Type | Description |
|---|---|---|
cmd |
List | Command to run. Required. |
env |
Object | Environment variables to set for this execution. |
run_on |
String | When to run the step: success, failure, or always. Default is success. |
Common Use Cases
Section titled “Common Use Cases”Require approval from specific team based on which resources were modified
Section titled “Require approval from specific team based on which resources were modified”Assuming a Rego policy file which defines a value networking_team_resources_modifed if any resources that the networking team manages have been modified, require someone from the networking team to approve the pull request before it can be applied.
workflows: - tag_query: "" plan: - type: init - type: plan - type: opa fail_on: defined extra_args: ['-d', 'policy.rego', 'data.terraform.networking_team_resources_modifed'] gate: any_of: ["team:networking"] any_of_count: 1Security Scan Overrides
Section titled “Security Scan Overrides”Allow security teams to approve known false positives or accepted risks:
workflows: - tag_query: "" plan: - type: init - type: plan - type: checkov gate: token: "checkov-override" any_of: ["team:security", "team:platform"] any_of_count: 1When Checkov detects issues, security or platform team members can review and approve if the findings are acceptable.
Policy Exception Handling
Section titled “Policy Exception Handling”Enable compliance teams to grant exceptions to policy violations:
workflows: - tag_query: "production" plan: - type: init - type: plan - type: conftest gate: token: "policy-exception" all_of: ["team:compliance"] any_of: ["user:compliance-lead", "user:ciso"] any_of_count: 1This requires both general compliance team approval and approval from either the compliance lead or CISO.
Cost Threshold Approvals
Section titled “Cost Threshold Approvals”Require finance approval when infrastructure changes exceed cost thresholds:
workflows: - tag_query: "" plan: - type: init - type: plan - type: run cmd: ['./scripts/cost-check.sh'] on_error: - type: gate token: "cost-threshold" any_of: ["team:finance", "user:budget-owner"] any_of_count: 1If the cost check script fails (indicating costs exceed thresholds), finance team members can review and approve the changes.
Multi-Stage Validation
Section titled “Multi-Stage Validation”Combine multiple gated checks with different approval requirements:
workflows: - tag_query: "production" plan: - type: init - type: plan
# Security scanning with override capability - type: checkov gate: token: "security-scan" any_of: ["team:security"] any_of_count: 1
# Compliance validation with stricter approval - type: conftest gate: token: "compliance-check" all_of: ["team:compliance"] any_of: ["user:compliance-lead"] any_of_count: 1
# Custom validation with multiple approvers required - type: run cmd: ['./scripts/validate-production.sh'] on_error: - type: gate token: "prod-validation" any_of: ["team:platform", "team:sre", "team:devops"] any_of_count: 2