Migrating to Approval Policies»
Info
This guide helps you migrate from deprecated initialization policies and task policies to the more powerful and flexible approval policies.
Why migrate?»
Approval policies provide a unified, more powerful approach to controlling runs and tasks:
- Unified policy type: One policy type for both runs and tasks instead of separate policies
- Human review workflows: Support manual approval/rejection with comments, not just automatic decisions
- Role-based approvals: Require specific teams or roles to approve changes
- Richer context: Access to reviews, run state, creator information, and more
- Flexible approval logic: Combine multiple conditions (e.g., "2 approvals + no rejections" or "Director approval OR both DevOps and Security")
- Better feedback: Descriptive approval/rejection reasons with
approve_with_noteandreject_with_note
Migration overview»
The migration pattern is straightforward:
Old pattern (init/task policies):
1 2 3 | |
1 2 3 | |
New pattern (approval policy):
1 2 3 4 | |
1 2 3 4 | |
Data input differences»
When migrating, be aware of these data structure changes between old and new policy types.
From initialization policies»
When migrating from initialization policies to approval policies, the input data structure changes:
| Old Location (Initialization Policy) | New Location (Approval Policy) | Notes |
|---|---|---|
input.commit |
input.run.commit |
Commit information (author, branch, hash, message) |
input.run |
input.run |
Run metadata - structure largely unchanged |
input.stack |
input.stack |
Stack metadata - structure largely unchanged |
input.request.timestamp_ns |
input.run.created_at |
Timestamp of when the run was created |
| N/A | input.reviews |
New: Contains approval/rejection reviews |
| N/A | input.run.creator_session |
New: Session info for the user who created the run |
| N/A | input.run.drift_detection |
New: Whether this is a drift detection run |
From task policies»
When migrating from task policies to approval policies, the input data structure changes:
| Old Location (Task Policy) | New Location (Approval Policy) | Notes |
|---|---|---|
input.request.command |
input.run.command |
The task command to execute |
input.session |
input.run.creator_session |
User who created the task run |
input.request.timestamp_ns |
input.run.created_at |
Timestamp of when the task was created |
input.request.remote_ip |
input.run.creator_session.creator_ip |
IP address of the user who created the task |
input.stack |
input.stack |
Stack metadata - structure largely unchanged |
| N/A | input.reviews |
New: Contains approval/rejection reviews |
| N/A | input.run.type |
New: Set to "TASK" for task runs |
Tip
The approval policy has access to richer context through input.reviews, which enables human review workflows. You can require specific teams or roles to approve runs/tasks, check the number of approvals/rejections, and more.
Initialization policy migration»
Initialization policies prevented runs from starting based on runtime configuration, commit details, or other pre-execution conditions.
Use case 1: Block dangerous before_init commands»
Scenario: Prevent users from running dangerous Terraform commands in before_init hooks, while allowing safe operations like formatting checks.
Old initialization policy:
1 2 3 4 5 6 7 | |
1 2 3 4 5 6 7 | |
New approval policy:
1 2 3 4 5 6 7 8 9 | |
1 2 3 4 5 6 7 8 9 | |
Enhanced with approval policy features:
You can now add descriptive feedback and allow manual override:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Use case 2: Enforce runner image compliance»
Scenario: Ensure runs only use approved Docker images to prevent malicious code execution.
Old initialization policy:
1 2 3 4 5 6 | |
1 2 3 4 5 6 | |
New approval policy:
1 2 3 4 5 | |
1 2 3 4 5 | |
Enhanced with approval policy features:
Support multiple approved images and require security team approval for exceptions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Use case 3: Enforce workflow requirements»
Scenario: Require that terraform fmt -check always runs first in the before_init sequence.
Old initialization policy:
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 | |
New approval policy:
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 7 8 9 10 | |
Enhanced with approval policy features:
Provide clearer feedback and allow overrides for emergency situations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Use case 4: Branch naming conventions»
Scenario: Enforce that feature branches follow a naming convention like feature/* or fix/*.
Old initialization policy:
1 2 3 4 5 6 7 | |
1 2 3 4 5 6 7 | |
New approval policy:
1 2 3 4 5 6 7 8 9 | |
1 2 3 4 5 6 7 8 9 | |
Enhanced with approval policy features:
Support ticket references and allow manual approval for hotfixes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
Task policy migration»
Task policies controlled which commands could be executed as tasks, preventing dangerous operations or restricting access based on user roles.
Use case 1: Command allowlisting»
Scenario: Only allow non-admins to run safe commands like terraform taint and terraform untaint.
Old task policy:
1 2 3 4 5 6 7 | |
1 2 3 4 5 6 7 | |
New approval policy:
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 7 8 9 10 | |
Enhanced with approval policy features:
Add a broader allowlist and require team lead approval for other commands:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
Use case 2: Time-based restrictions»
Scenario: Prevent tasks from running on weekends.
Old task policy:
1 2 3 4 5 6 7 | |
1 2 3 4 5 6 7 | |
New approval policy:
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 7 8 9 10 | |
Enhanced with approval policy features:
Allow emergency tasks with proper approval:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
Use case 3: Command validation by resource criticality»
Scenario: Allow simple state operations on all resources, but require approval for changes to critical infrastructure.
Old task policy (limited approach):
1 2 3 4 5 6 7 | |
1 2 3 4 5 6 7 | |
New approval policy (enhanced approach):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
Combined patterns»
One of the most powerful features of approval policies is the ability to handle both runs and tasks in a single policy, with unified approval logic.
Unified approval workflow»
This policy combines initialization and task policy concerns with a consistent approval workflow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
Migration checklist»
Use this checklist when migrating your policies:
- Identify all initialization and task policies attached to your stacks
- For each policy:
- Review the use case and requirements
- Convert
denyrules torejectrules - Add
approve if not rejectrule - Update data input references (see Data input differences)
- Consider enhancements:
- Add descriptive feedback with
reject_with_noteandapprove_with_note - Add manual approval workflows for exceptions
- Add role-based approval requirements
- Combine related policies into a unified approval policy
- Add descriptive feedback with
- Test the new policy using the policy workbench
- Use the
samplerule to capture real evaluation data
- Deploy the new approval policy
- Attach to the same stacks as the old policy
- Monitor initial runs to ensure correct behavior
- Remove old policies once the new approval policy is validated
- Update documentation for your team about the new approval workflows
Testing your migration»
Use Spacelift's policy workbench to test your new approval policies before deploying them:
-
Add a
samplerule to your approval policy to capture evaluations:1sample if true # Capture all evaluations1sample { true } # Capture all evaluations -
Attach the policy to a test stack
- Trigger a test run or task
- Open the policy workbench and review the captured input
- Adjust your policy logic as needed
- Simulate with different inputs to verify behavior
- Remove or refine the
samplerule before production deployment
Getting help»
If you need assistance with your migration:
- Review the approval policy documentation for detailed information.
- Check the policy examples library.
- Use the policy workbench to test and debug policies.
- Contact Spacelift support for custom policy assistance.