Drift Detection False Positives in Notification Policies
Last updated: September 9, 2025
When using drift detection with notification policies, you may notice that your policy triggers webhooks even when Spacelift's UI shows "No Changes." This happens because of how Spacelift handles drift detection data in different contexts.
Why This Happens
Spacelift's drift detection process works in two phases:
Initial draft plan: Spacelift runs a draft Terraform plan and streams the raw output to logs, which may include false positives
Final analysis: Spacelift re-reads the plan, filters out false positives, and updates the UI to show the accurate result
The key difference is in how data is presented:
UI and webhook payload: Show filtered results with false positives removed (using the
run.deltaobject)Policy input: Contains the full raw list of detected changes in the
.changesfield, including no-ops and false positives
This design gives you maximum flexibility in policy evaluation while keeping the UI clean.
Solution: Filter No-Op Actions in Your Policy
To align your notification policy with what's shown in the UI, you need to exclude no-op actions in your policy logic. Here's how to modify your policy:
package spacelift
import future.keywords.in
webhook[{"endpoint_id": "driftdetectionwh"}] {
# Checking if drift detection is present in the run update
input.run_updated.run.drift_detection == true
# Filter out no-op changes and count only meaningful changes
meaningful_changes := [change |
change := input.run_updated.run.changes[_]
change.action != "no-op"
]
# Condition to verify that there is at least one meaningful change
count(meaningful_changes) > 0
some label in input.run_updated.stack.labels
label == "U12"
}
sample := trueThis modification filters out changes where action == "no-op", ensuring your policy only triggers for actual changes that require attention.
For more details on notification policy filtering, see the notification policy documentation.