Terraform Cloud runs a plan, someone reviews it, and then apply changes real infrastructure — a workflow that has one obvious weak point: nothing stops a misconfigured aws_s3_bucket or an overly permissive google_project_iam_binding from reaching apply as long as the plan is syntactically valid. Snyk IaC closes part of that gap using a native HashiCorp extension point called run tasks. Rather than requiring teams to bolt scanning onto CI or trust a human reviewer to catch every misconfiguration in a plan diff, Snyk registers itself as a callback that Terraform Cloud invokes mid-run, scans the generated plan, and reports a pass/fail status back before the run is allowed to continue. This post walks through the mechanics publicly documented by HashiCorp and Snyk: how run tasks are wired into the run lifecycle, what payload Snyk actually receives, how enforcement levels change what happens on a failed scan, and where this gate sits relative to Terraform Cloud's other guardrails.
What are Terraform Cloud run tasks, and why do they exist?
Run tasks are a Terraform Cloud/Enterprise feature, generally available since 2021, that let an external HTTP service participate in a run before it completes. HashiCorp built them specifically so third-party security, cost, and compliance tools didn't need custom CLI wrappers or post-hoc reconciliation — instead, the platform itself calls out to a registered endpoint at a defined point in the run and waits for a verdict. A run task is configured once at the organization level with a URL and a shared HMAC secret, then attached to one or more workspaces with a chosen stage and enforcement level. Terraform Cloud supports attaching tasks at the post-plan stage (after a plan is generated, before apply) and, in later platform versions, a pre-apply stage that sits even closer to the apply step. Snyk's integration uses the post-plan stage, meaning it evaluates the concrete plan output rather than raw HCL source.
How does Snyk IaC actually plug into a Terraform Cloud run?
It plugs in as a registered run task endpoint that Terraform Cloud calls automatically on every run in an attached workspace. In Snyk's IaC settings, an admin creates a Terraform Cloud integration, which generates an endpoint URL and a secret; that pair is then entered into Terraform Cloud's organization-level Run Tasks settings and attached to specific workspaces. From that point on, every terraform plan executed in that workspace triggers an outbound webhook from Terraform Cloud to Snyk containing run metadata — organization name, workspace ID, run ID, a callback URL for reporting the result, and (for post-plan) a reference the task can use to retrieve the plan's JSON output via the Terraform Cloud API. The request is signed with the shared secret so Snyk can verify it genuinely came from Terraform Cloud before acting on it.
What does Snyk actually scan, and against what rules?
Snyk pulls the structured plan JSON — not the raw .tf files — and evaluates the resources it describes against its IaC rule set, the same policy engine behind snyk iac test and the Snyk web UI scans. That means checks covering common misconfiguration classes across AWS, Azure, GCP, and Kubernetes resources: publicly exposed storage buckets, security groups open to 0.0.0.0/0, disabled encryption at rest, overly broad IAM policies, missing logging, and similar patterns Snyk maintains as built-in rules, with support for custom rules for organizations that need provider- or org-specific policy. Because it reads the plan rather than the source, it sees the resolved values after variables, modules, and workspace-specific inputs are applied — closer to what will actually be created than a static scan of a .tf file in a repo.
What happens when the scan finds something — does it actually block the run?
Whether a failed scan blocks anything depends entirely on the enforcement level chosen when the run task was attached to the workspace: advisory or mandatory. In advisory mode, Snyk reports its findings and a pass/fail status back to Terraform Cloud, which surfaces them in the run UI with a link to the detailed results in Snyk, but the run is allowed to proceed to apply regardless of outcome. In mandatory mode, a failed run task result halts the run before it can reach the apply stage; someone with the appropriate workspace permissions must either fix the configuration and trigger a new plan or explicitly override the failed task to let the existing run proceed. This is the mechanism that turns a scan into an actual gate rather than a dashboard notification — without mandatory enforcement, run tasks are visibility, not policy.
How does this compare to Sentinel or OPA policy checks in Terraform Cloud?
It's a parallel, additive gate rather than a replacement for HashiCorp's own policy-as-code tooling. Terraform Cloud's Sentinel (and, on newer plans, OPA) policy checks run natively inside the platform and are typically used for org-specific guardrails like tagging standards, allowed instance types, or cost ceilings written by the platform team itself. Run tasks, by contrast, delegate the actual evaluation to an external vendor's engine and rule content — Snyk's maintained vulnerability and misconfiguration database — which the customer doesn't have to write or maintain themselves. A workspace can have both a mandatory Sentinel policy set and a mandatory Snyk run task active at once; either one failing can independently block the run from reaching apply, since both are enforced at different points in the same pipeline.
What are the practical limits of this gate?
The biggest limitation is availability and placement: run tasks require Terraform Cloud's paid tiers (not the free tier) and, for Snyk specifically, only fire at post-plan, meaning a plan still has to be generated — and its cost/time paid — before the gate can reject it. It's also a per-workspace opt-in; a workspace where no one attached the run task gets no coverage at all, so consistency depends on org-wide enforcement of workspace configuration rather than anything inherent to the scanner. Because the check operates on the plan JSON at run time, it can't catch issues introduced between plan and apply if a workspace is configured to auto-apply without regenerating a plan, and like any misconfiguration scanner, it's bounded by the coverage of its rule set — provider resource types Snyk hasn't written rules for pass through with no signal either way.
How Safeguard Helps
Run tasks are a solid enforcement point for the specific problem they target — misconfigurations visible in a Terraform plan — but they only see one slice of what actually reaches production: the resource-level plan for one workspace at one point in the pipeline. Safeguard is built to give teams the surrounding context that a single IaC gate doesn't provide — tracking which module and provider versions are pinned across every workspace, flagging when a Terraform Cloud run task, Sentinel policy, or OPA check is missing, misconfigured, or set to advisory instead of mandatory, and correlating infrastructure changes with the CI/CD identities and commits that produced them. Rather than asking teams to trust that every workspace has the right gate attached, Safeguard treats the enforcement configuration itself as an auditable, continuously verified control — so a gap in how Terraform Cloud, Snyk, or any other tool was wired up shows up as a finding before it becomes an incident.