Migrating to Approval Policies»
Info
This guide helps you migrate from deprecated server-side 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 server-side initialization policies»
When migrating from server-side initialization policies to approval policies, the input data structure changes:
| Old Location (Server-Side 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.
server-side initialization policy migration»
Server-side 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 server-side 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 server-side 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 server-side 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 server-side 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.