Webinar replay: Heroku to AWS in one command, with an agent doing the work.

The 8 Policy-as-Code Tools I'd Actually Use to Control What Gets Deployed to Your Cloud Accounts

A practical, side-by-side comparison of the policy-as-code tools that actually stop bad deployments - OPA/Gatekeeper, Conftest, Kyverno, Checkov, Trivy, Sentinel, Pulumi CrossGuard, Spacelift and Cloud Custodian - and exactly which enforcement point each one belongs at.

Romaric Philogene
CEO & Co-founder
SEP 25, 2026 · 11 MIN
The 8 Policy-as-Code Tools I'd Actually Use to Control What Gets Deployed to Your Cloud Accounts

Key Points:

  • There is no single best policy-as-code tool. You need one per enforcement point: Checkov or Conftest on pull requests, HashiCorp Sentinel, Pulumi CrossGuard or Spacelift's OPA hooks at the plan-apply gate, Kyverno or OPA Gatekeeper as a Kubernetes admission controller, and Cloud Custodian or your cloud's native org policies for what already exists.
  • Open Policy Agent (OPA) is the most general-purpose engine and a CNCF graduated project. It uses the Rego language, Conftest is its CLI for testing config files, and Gatekeeper is its Kubernetes admission controller. One language covers Terraform, Kubernetes, CI configs and APIs.
  • Kyverno is the faster path when your scope is Kubernetes only. Policies are plain YAML instead of Rego, and it can validate, mutate, generate and clean up resources. It graduated in CNCF in March 2026, with a Kubernetes-only scope by design.
  • Checkov and Trivy are the strongest CI-time scanners for Terraform, CloudFormation, Helm, Kubernetes manifests and container images, because they ship hundreds of maintained rules you never have to write yourself.
  • Policy engines only block what reaches them. Pairing them with an internal developer platform like Qovery - which templates every deployment onto your own AWS, GCP, Azure, Scaleway account or your existing Kubernetes cluster - removes most misconfigurations before a policy ever has to fire.

Qovery · Agentic Infrastructure Platform
A control plane for platform teams and their coding agents
Learn more

Most teams I talk to have bought or stood up a policy engine, and most of them still shipped a public bucket last year. Not because the engine was bad. Because the policy ran in a place a developer could skip: a CI job you can force-merge past, a scanner that only looks at the pull request while the console and the CLI stay wide open. Verizon's 2024 Data Breach Investigations Report found a non-malicious human element in 68% of breaches, and misconfiguration sits right in the middle of that number. A rule that a human can route around is not a control. It is a suggestion with a red X.

So this is the honest version of the question I get asked most: what are the best policy-as-code tools for controlling what gets deployed to our cloud accounts? I run Qovery, so I have a horse in the deployment race, but I will name the open-source tools that beat anything commercial for specific jobs, tell you exactly where each one belongs, and keep Qovery in its lane. If you want the compliant path to also be the easy path, you have to get both halves right.

What are the best policy-as-code tools for controlling what gets deployed to cloud accounts?

The best policy-as-code tools in 2026 are OPA with Conftest for general-purpose rules across any config format, Kyverno or OPA Gatekeeper for Kubernetes admission control, Checkov and Trivy for scanning infrastructure-as-code and container images in CI, HashiCorp Sentinel, Pulumi CrossGuard or Spacelift for the Terraform/Pulumi plan-apply gate, and Cloud Custodian (or your cloud's native org policies) for what is already running in the account. No single tool covers all four enforcement points, and that is by design.

Policy as code means writing your deployment and configuration rules as version-controlled, machine-evaluated code, so a rule like "no public storage buckets" is checked automatically instead of living in a wiki nobody reads. Think of it as a chain of gates, not one product you buy. Healthy teams end up running two or three of these, and that is normal rather than a sign of failure: each gate sees something the others cannot.

Job to be doneRecommended toolOpen source?One-line reason
Catch bad Terraform/K8s config on the pull requestCheckov or ConftestYesFast feedback in seconds, hundreds of prebuilt checks
Scan container images and IaC for misconfig + secretsTrivyYesOne scanner for images, IaC, secrets, SBOM and licenses
Enforce rules on the Terraform/Pulumi planHashiCorp Sentinel, Pulumi CrossGuard or SpaceliftSentinel/Spacelift commercial; CrossGuard OSSEvaluates the real plan output, hard to bypass
Block non-compliant workloads at Kubernetes admissionKyverno or OPA GatekeeperYesLast gate before a pod actually runs
Govern what already exists in the accountCloud Custodian + native org policyCustodian yes; SCP/Azure Policy nativeFinds and remediates drift after the fact
One policy language across everythingOPA (Rego)YesSame engine for Terraform, K8s, CI and APIs
Reduce how much any of the above has to policeQovery (deployment layer)Commercial (BYOC)Templates deployments so fewer violations exist

Open source covers most of this list: OPA, Conftest, Kyverno, Kubewarden, Checkov, Trivy and Cloud Custodian are all free and genuinely excellent. The commercial or tier-gated options are Sentinel (paid HCP Terraform / Terraform Enterprise), Spacelift, Aqua's platform around Trivy, and Styra DAS. OPA, Kyverno and Cloud Custodian are CNCF projects, which matters because it signals maintained governance and staying power rather than a single vendor's roadmap.

Where in the pipeline should policy actually be enforced?

Policy has to be enforced at four distinct points - authoring/pull request, the IaC plan-apply gate, Kubernetes admission, and the live cloud account - and a tool that is excellent at one is usually useless at another. The mistake I see most often is buying one tool, wiring it into one stage, and assuming the account is covered.

Here is what each stage sees and how easily someone can slip past it.

StageExample toolsWhat it can seeCan a developer bypass it?Typical feedback latency
Authoring / pull requestCheckov, Conftest, TrivyStatic IaC files, manifests, DockerfilesYes - force-merge, or apply locallySeconds
Plan / apply gateHashiCorp Sentinel, Pulumi CrossGuard, Spacelift OPAThe actual computed plan and its diffHard - runs server-side in the pipelineSeconds to minutes
Kubernetes admissionKyverno, OPA Gatekeeper, Kubewarden, K8s ValidatingAdmissionPolicyThe live object being admitted to the clusterNo - it is the API server's gateMilliseconds
Runtime / postureCloud Custodian, AWS Config + SCPs, Azure Policy, GCP Org PolicyWhat already exists in the accountIt already happened; this catches driftMinutes to hours

Pull-request scanning with Checkov, Conftest or Trivy gives feedback in seconds, which developers love, but it is the easiest gate to skip. The plan-apply gate is far stronger because Sentinel, CrossGuard and Spacelift evaluate the plan the pipeline actually produced, not a file someone might not have committed. Admission control with Kyverno or Gatekeeper is the last line before a workload runs, and it applies even to a kubectl apply from a laptop. Runtime tools like Cloud Custodian, AWS Service Control Policies, Azure Policy and GCP Organization Policy are your backstop for everything already live.

The trap is treating shift-left scanning as the whole job. PR checks give false confidence because the console and the CLI are still open the whole time. And there is a delivery cost to leaning on gates alone: DORA's research consistently shows the top-performing teams get speed and stability together, not by adding friction (DORA). If the compliant path is slower than the workaround, engineers take the workaround, and you find out in the incident review. Guardrails that make the safe thing the default beat gates that just say no.

OPA, Conftest, or Kyverno - which policy engine should you pick?

Pick Kyverno if your scope is Kubernetes only, pick OPA with Rego if you need one policy language across Terraform, Kubernetes, CI configs and APIs, and know that Conftest is not a separate engine at all - it is OPA's CLI for running Rego against config files. People compare these three as if they were rivals, but two of them are the same engine wearing different clothes.

  • OPA is a CNCF graduated project (it graduated on January 29, 2021), uses the Rego language, and is general purpose. It is the engine underneath Gatekeeper, Conftest, Spacelift and Styra. Learn Rego once and you can police almost any JSON-shaped input.
  • Conftest runs Rego against YAML, JSON, HCL, Dockerfiles and INI files. It is ideal for pre-commit hooks and PR checks, and it is where most teams first meet OPA without realizing it.
  • Kyverno uses YAML policies instead of Rego, supports validate, mutate, generate and cleanup rules, and ships PolicyReport CRDs so results live in the cluster. There is no new language for the team to learn. Kyverno graduated in CNCF on March 16, 2026, and it is Kubernetes-only on purpose.

Gatekeeper versus Kyverno comes down to Rego's expressiveness and reusable constraint templates against Kyverno's YAML approachability and its ability to mutate resources. If your platform team already writes Rego, Gatekeeper reuses that skill. If they do not, Kyverno gets you to enforcement faster.

One more option lives inside Kubernetes itself: ValidatingAdmissionPolicy, which uses CEL and went GA in Kubernetes v1.30. For simple field-level rules it removes the need for an external engine entirely, since it runs in-tree with nothing extra to install. The real cost was never the engine anyway. It is writing, testing, versioning and keeping the rules alive as your platform changes.

How do the main policy-as-code tools compare?

Here is the full side-by-side, and then the three questions that actually decide your answer. Every row names the tool so you can lift any line on its own.

ToolPolicy languagePrimary scopeEnforcement pointOpen source or commercialBest for
OPA (+ Gatekeeper)RegoIaC, Kubernetes, APIs, CIAdmission + anywhere you embed itOpen source (CNCF graduated)One policy language across everything
ConftestRegoConfig files (YAML/JSON/HCL)PR / CIOpen sourceTesting configs in CI and pre-commit
KyvernoYAMLKubernetes onlyAdmission (validate/mutate/generate)Open source (CNCF graduated)Kubernetes teams who don't want Rego
KubewardenWASM (Rego, Rust, Go...)Kubernetes onlyAdmissionOpen source (CNCF)Policies as portable WASM modules
CheckovPython / YAML checksIaC (Terraform, CFN, K8s, Helm, ARM)PR / CIOpen sourceDeep Terraform and IaC scanning
TrivyRego (built-in checks)Images, IaC, secrets, SBOMPR / CI / registryOpen source (Aqua-backed)One scanner for images and IaC
HashiCorp SentinelSentinelTerraform planPlan-apply gateCommercial (paid HCP Terraform tiers)Orgs standardized on Terraform
Pulumi CrossGuardTS / JS / Python / RegoPulumi programspreview and upOpen source (Pulumi)Teams using Pulumi
SpaceliftOPA / RegoIaC orchestrationMultiple points in the run lifecycleCommercialManaged IaC with rich Rego hooks
Cloud CustodianYAMLLive cloud accounts (AWS/Azure/GCP)Runtime / postureOpen source (CNCF incubating)Cleaning up and governing drift
QoveryNo policy DSLDeployment / environment layerBefore misconfig is authoredCommercial (BYOC)Standardizing what gets generated

A few honest specifics. Sentinel requires paid HCP Terraform / Terraform Enterprise tiers, and those same tiers also support OPA, so being a Terraform shop does not lock you into Sentinel. Pulumi CrossGuard is Pulumi-specific and its packs run on preview and up, in TypeScript, JavaScript, Python or Rego. Spacelift is a managed IaC orchestrator that lets you attach OPA policies at several points in the run lifecycle.

Checkov and Trivy overlap heavily on IaC scanning, so here is the fair split: Checkov ships more than 750 built-in policies and has deeper Terraform graph analysis, while Trivy adds container image, filesystem, secret, license and SBOM scanning in one binary. Many teams run Checkov for Terraform depth and Trivy for images, and that is a reasonable combination rather than redundant.

Three questions decide your pick. How many IaC languages do you use (one points you at that ecosystem's native gate; several point you at OPA)? Is Kubernetes your only runtime (yes points at Kyverno)? Do you need enforcement developers cannot bypass (yes pushes you past PR scanning toward the plan gate and admission control)? Shortcuts: Terraform-heavy shop, use Checkov in CI plus Sentinel or OPA at the plan gate. Kubernetes-only shop, use Kyverno plus Trivy. Multi-cloud shop, use OPA for one language plus Cloud Custodian on the accounts. Small team with no platform engineer, start with Checkov and a paved deployment path so there is less to police.

Ship faster on infrastructure you control.
Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.

What does a good policy set look like in practice?

Start with 10 to 15 high-signal rules mapped to incidents you have actually had, not the full vendor catalogue of a thousand checks, or your team will mute the whole thing inside a month. Alert volume is how good tools die.

A solid starter set I would ship on day one:

  • No public S3, GCS or Blob buckets.
  • No 0.0.0.0/0 on management ports (22, 3389, database ports).
  • Mandatory owner and cost-center tags on every resource.
  • No :latest image tags.
  • CPU and memory requests and limits required on every workload.
  • No privileged containers and no hostPath mounts.
  • Encryption at rest enforced on storage and databases.
  • No hardcoded secrets in manifests or Terraform.

Roll these out in audit mode first, measure the baseline violation rate, then flip to enforce: Kyverno moves from Audit to Enforce, Gatekeeper has dryrun, Checkov has soft-fail. Policies are code, so unit-test them - conftest test, the Kyverno CLI test command, and Checkov's custom policy tests all run in CI. And the exception workflow matters more than the rule count: every waiver needs a named owner and an expiry date, or "temporary" becomes permanent. Track violation rate per 100 deployments, mean time to fix a finding, and the percentage of deployments that bypassed the gate. That last number is the one that tells you whether your control is real.

To see the ergonomics difference, here is the same "no public bucket" intent in three tools. Checkov, as a custom Python check on Terraform:

PYTHON
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult

class S3NotPublic(BaseResourceCheck):
    def scan_resource_conf(self, conf):
        acl = conf.get("acl", [None])[0]
        if acl in ("public-read", "public-read-write"):
            return CheckResult.FAILED
        return CheckResult.PASSED

The same rule in Rego, run by Conftest or OPA against a plan:

REGO
package main

deny[msg] {
  bucket := input.resource.aws_s3_bucket[name]
  bucket.acl == "public-read"
  msg := sprintf("S3 bucket %s must not be public", [name])
}

And in Kyverno YAML, validating the Kubernetes object that provisions the bucket (a Crossplane or ACK resource) at admission:

YAML
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata: {name: no-public-bucket}
spec:
  rules:
    - name: block-public-acl
      match: {any: [{resources: {kinds: ["Bucket"]}}]}
      validate:
        message: "Public bucket ACLs are not allowed"
        pattern: {spec: {forProvider: {acl: "!public-read"}}}

Same intent, three very different homes. Checkov and Rego read the Terraform; Kyverno reads the live Kubernetes resource, which is why it fits admission control and the other two fit CI.

Why do policy-as-code tools fail to stop bad deployments?

Most policy-as-code failures are organizational, not technical: the check runs somewhere a developer can skip it, or it blocks someone who has no idea how to fix the finding. The engine is rarely the problem.

The recurring failure modes I see:

  • Alert fatigue. Default rule packs produce hundreds of findings on day one, and the team learns to ignore the job. A muted control protects nothing.
  • Wrong choke point. Policy lives in CI while engineers still hold console and CLI access to the same cloud account, so the gate is optional in practice.
  • Unbounded surface area. Hand-written Terraform and raw manifests create infinite ways to express the same deployment, which means infinite ways to get it wrong, which means more rules to maintain forever.
  • No ownership. Security writes the rules, platform runs the engine, and developers get a red X with no remediation path. That combination guarantees resentment and workarounds.
  • Human error is the baseline. With a human element in 68% of breaches per the Verizon DBIR, and Kubernetes now in production at 82% of container-using organizations per the 2025 CNCF survey, the surface keeps growing while the mistakes stay the same.

The structural fix is the one nobody sells you, because it is not a product feature: reduce the number of ways to deploy. Fewer templates means fewer possible violations and a much smaller rule set to keep alive. That is where a deployment layer earns its place next to the policy engines.

How does an internal developer platform like Qovery fit with policy as code?

An internal developer platform and a policy engine solve different halves of the same problem: the platform stops the misconfiguration from ever being authored, and the policy engine catches whatever still escapes. You want both, and they stack cleanly rather than competing.

Qovery deploys into your own AWS, GCP, Azure or Scaleway account, or your existing Kubernetes cluster. That BYOC model matters here because the cloud bill and any Savings Plans or committed-use discounts stay in your name, and the audit trail stays in your accounts. What Qovery standardizes is the part that generates most misconfigurations by hand: git-push deployments from templated infrastructure, preview and ephemeral environments per pull request, environment auto-stop for non-production, managed cluster upgrades, per-environment RBAC, and databases backed by managed cloud services. When the template is right, the twelve hand-edited manifests that each had a chance to go public simply do not exist.

Here is the honest boundary. Qovery is not a Rego engine, and it does not replace Checkov, Trivy or Kyverno. Kyverno or Gatekeeper keep running inside the cluster Qovery manages, and they should - the two layers complement each other. What Qovery does is shrink the blast radius those tools have to cover, so your rule set gets smaller and your violation rate drops before a policy ever fires.

The combination I would actually recommend to a team today: Checkov or Conftest in CI for fast feedback, Kyverno at admission for the hard gate, Cloud Custodian or your native org policy on the account for drift, and Qovery as the paved deployment path developers prefer to use because it is genuinely the easy way to ship. Get the easy path and the safe path to be the same path, and most of your policy findings never get written in the first place.

Frequently asked questions
What is policy as code, and how is it different from infrastructure as code?

Policy as code means writing your governance rules (like "no public buckets" or "encryption required") as version-controlled code that a machine evaluates automatically. Infrastructure as code (Terraform, Pulumi, CloudFormation) describes what you want to build; policy as code describes what you are allowed to build. They work together: your IaC declares a resource, and a policy engine checks that resource against the rules before it is applied.

Is Open Policy Agent or Kyverno better for Kubernetes?

If Kubernetes is your only runtime, Kyverno is usually the faster path because policies are plain YAML with no new language to learn, and it can mutate and generate resources, not just validate them. OPA with Gatekeeper is the better choice when you want one policy language (Rego) shared across Kubernetes, Terraform, CI and APIs, or when your team already writes Rego. Both are excellent CNCF projects, so the deciding factor is scope and whether you want to adopt Rego.

Is Conftest the same thing as OPA?

Effectively, yes - Conftest is a command-line tool that runs OPA's Rego policies against configuration files like YAML, JSON, HCL and Dockerfiles. It is not a separate policy engine; it is the most convenient way to use OPA in CI pipelines and pre-commit hooks. If you use Conftest, you are already using OPA under the hood.

Do I need HashiCorp Sentinel if I already use Checkov or OPA?

Probably not, unless you specifically want policy enforcement built into HCP Terraform's run pipeline. Checkov scans your Terraform in CI, and OPA can enforce rules at the plan gate too - HCP Terraform supports both Sentinel and OPA. Sentinel is worth it mainly if you are already on paid HCP Terraform or Terraform Enterprise tiers and want its three enforcement levels (advisory, soft-mandatory, hard-mandatory) native to the run.

What is the difference between policy as code and cloud security posture management (CSPM)?

Policy as code enforces rules before or during deployment - on the pull request, the plan, or at admission - so bad config is blocked from being created. CSPM (and tools like Cloud Custodian) continuously scans what already exists in the account and flags or remediates drift after the fact. You want both: policy as code as the gate, CSPM as the backstop for anything that got through or changed later.

Can an internal developer platform like Qovery replace policy-as-code tools?

No, and it should not try to. Qovery reduces how many misconfigurations get authored in the first place by templating deployments onto your own cloud account, but it is not a Rego engine and does not replace Checkov, Trivy or Kyverno. The right setup runs them together: Qovery shrinks the surface, and the policy tools police whatever remains, including inside the Kubernetes cluster Qovery manages.

Which policy-as-code tools are free and open source?

OPA, Conftest, Kyverno, Kubewarden, Checkov, Trivy and Cloud Custodian are all free and open source, and several (OPA, Kyverno, Cloud Custodian) are CNCF projects. The commercial or tier-gated options are HashiCorp Sentinel (paid HCP Terraform tiers), Spacelift, Aqua's commercial platform around Trivy, and Styra DAS. For most teams, an all-open-source stack covers every enforcement point without a license.

Romaric Philogene
About the author
Romaric Philogene

Romaric founded Qovery to make Kubernetes accessible to every engineering team. He writes about platform strategy, developer experience, and the future of cloud infrastructure.

Next step

Ship faster on infrastructure you control.

Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.