IaC Security Scanning: How It Works, Key Tools, and Best Practices
You can catch a public Amazon Simple Storage Service (S3) bucket, a wildcard identity and access management (IAM) role, or a hardcoded Amazon Web Services (AWS) access key before it reaches production.
Infrastructure as code (IaC) security scanning runs static analysis on Terraform, CloudFormation, Kubernetes manifests, and similar files against a policy library before anything deploys. A flawed Terraform module reaches every environment that applies it, and catching the problem before the module merges stops that spread with one fix.
This guide covers how the scan cycle works and what it flags, how the scanners compare, and where static scanning hands off to runtime posture monitoring.
What Is IaC Security Scanning?
IaC scanning is static analysis applied to infrastructure definitions. It checks each template against security and compliance rules on its own, before any of it runs, while static application security testing (SAST) looks at application source code and dynamic application security testing (DAST) probes the running application from outside.
Scanners accept the common IaC formats your team already writes. Terraform and Pulumi describe cloud resources in a declarative language, CloudFormation and Azure Resource Manager (ARM) templates (along with Bicep, its more compact syntax) define AWS and Azure resources in JSON or YAML, Kubernetes manifests and Helm charts specify workloads running in a cluster, and Ansible playbooks script configuration changes across servers.
Checkov, Trivy, and Terrascan are three widely used open-source scanners that read those formats and flag misconfigured resources. None of them parse Pulumi, which the commercial scanners Wiz and Checkmarx cover.
How IaC Security Scanning Works
A scanner reads your configuration files without touching the cloud account, which means you can run it through integrated development environment (IDE) plugins while you write a template. It doesn’t need cloud credentials for that check, and you get feedback early in development.
The cycle has five steps:
- Discover IaC files in a directory or repository.
- Match each resource block against a policy library.
- Record a pass or fail per resource.
- Score failures by severity, which Checkov does only with a Prisma Cloud application programming interface (API) key.
- Return remediation guidance in the IDE or pull request (PR).
Checkov’s CKV_AWS_16 shows how a single rule plays out in practice. It fails any Amazon Relational Database Service (RDS) aws_db_instance block that doesn’t set storage_encrypted = true and reports the file path and line range of the offending resource. Adding storage_encrypted = true to that block flips the next scan to passed, and the re-scan shortens your mean time to repair for misconfigurations by confirming the fix in seconds.
Why Scanning Templates Before Deployment Pays Off
Pre-deployment scanning catches a flaw once in the template instead of once per account that applies it. Third-party modules often carry insecure defaults, and those defaults become the baseline configuration everywhere the module runs.
Blocking the module at merge keeps the problem out of every workspace that depends on it.
Catching a Flawed Module Before Merge Stops It from Spreading
A finding in a PR costs a comment and a commit, while the same finding in production costs a change window, an incident review, and possibly a disclosure. The bigger saving comes from replication.
Catching a flawed module before merge keeps it out of every workspace that depends on it, and one fix in the module protects every account that consumes it.
Policy as Code Turns Compliance into Version-Controlled Rules
Policy as code (PaC) stores machine-readable infrastructure rules that live in Git beside the templates they govern. IaC declares what gets built. PaC declares the constraints it must meet, such as storage encrypted at rest, no security group open to 0.0.0.0/0, or databases in private subnets.
Commercial scanners typically map their built-in policies to compliance frameworks such as the Center for Internet Security (CIS) Benchmarks, the Payment Card Industry Data Security Standard (PCI DSS), and the Health Insurance Portability and Accountability Act (HIPAA).
Common Vulnerabilities and Misconfigurations IaC Scanning Catches
Scanners publish their rules as stable identifiers (IDs), so you can suppress one, override its severity, or map it to a control. These rules cover access, encryption, workload security, and exposed credentials. Common categories include:
- Overpermissive access: Checkov CKV_AWS_62 and CKV_AWS_63 fail IAM policies that grant full administrative privileges or a wildcard action. CIS AWS Foundations Benchmark v1.4.0 control 1.16 and Security Hub IAM.1 describe the same full-admin condition for live accounts.
- Missing encryption: CKV_AWS_3 fails an Amazon Elastic Block Store (EBS) aws_ebs_volume that doesn’t set encrypted = true. For data in transit, CKV_AWS_379 checks S3 buckets that have a public access control list (ACL) and no website configuration, and it fails them unless a bucket policy enforces secure transport.
- Insecure workloads: On Kubernetes manifests, CKV_K8S_23 fails a Pod with no securityContext because it may run as root, and CKV_K8S_16 fails a privileged container. Pod Security Admission enforces the Pod Security Standards for root and privileged settings at admission.
- Exposed secrets: CKV_AWS_41 fails a Terraform provider “aws” block containing a literal access_key = “AKIA…”. The regex-based CKV_SECRET family catches AWS keys, Azure storage keys, and basic-auth strings, and the –scan-secrets-history flag extends that search into past commits.
Together, these checks cover both resource-level configuration and credentials embedded in your repository. Stable rule IDs also give your team a consistent way to document exceptions and map findings to controls.
Key IaC Security Scanning Tools
The table compares three open-source and three commercial scanners based on each vendor’s documentation. Two recent events shape how you adopt them. Tenable archived Terrascan on November 20, 2025, and its ruleset no longer receives updates.
In March 2026, an attacker used compromised credentials to publish a malicious Trivy v0.69.4 and force-push tags in aquasecurity/trivy-action and aquasecurity/setup-trivy. Pin those actions by commit hash and stay on the advisory’s safe versions (Trivy v0.69.3, trivy-action v0.35.0, and setup-trivy v0.2.6).
| Tool | License | IaC formats (vendor docs) | Policy engine | Standout |
| Checkov | Apache-2.0 | Terraform, CloudFormation, Kubernetes, Helm, Kustomize, Ansible, Bicep, ARM, Dockerfile | Python and YAML, plus graph-based composite policies | 1,000+ built-in policies; Static Analysis Results Interchange Format (SARIF), JUnit Extensible Markup Language (XML), and CycloneDX output |
| Trivy | Apache-2.0 | Terraform, CloudFormation, Kubernetes, Helm, ARM, Dockerfile | Rego and Go, custom Rego supported | Vulnerability, misconfiguration, secret, and license scans in one binary |
| Terrascan | Apache-2.0 | Terraform, CloudFormation, ARM, Kubernetes, Helm, Kustomize, Dockerfile | Rego via Open Policy Agent (OPA) | OPA-native policies; repository archived |
| Snyk Infrastructure as Code | Commercial (Free, Team, Enterprise tiers) | Terraform (single file), CloudFormation, ARM (command line only), Kubernetes, Helm (Git integration only) | Rego custom rules | Inline fix advice in Visual Studio Code (VS Code), JetBrains, Eclipse, and Visual Studio |
| Wiz Code | Commercial | Terraform, CloudFormation, Bicep, Pulumi | Not documented in sources reviewed | Code-to-cloud mapping to module, file, line, and author |
| Checkmarx One IaC | Commercial (custom quote) | Formats including Terraform, Pulumi, Crossplane, Helm, Kubernetes, CloudFormation, ARM, Ansible | Rego queries in KICS, its open-source scanner | Cloud Insights traces runtime findings to the repository and container image |
Open-Source Scanners: Checkov, Trivy, and Terrascan
The open-source scanners differ in policy design and scan coverage:
- Checkov: Checkov adds graph-based composite policies that evaluate relationships between resources rather than one block at a time. In GitHub Actions, its SARIF output uploads to GitHub code scanning through github/codeql-action/upload-sarif.
- Trivy: Trivy runs vulnerability, misconfiguration, secret, and license scanners in one binary and accepts custom Rego.
- Terrascan: Terrascan uses OPA-native policies that no longer receive updates.
These differences help you choose between relationship-aware policies, a multi-purpose scanner, and an archived OPA-native ruleset.
Commercial Scanners: Snyk, Wiz, and Checkmarx
The commercial scanners pair IaC findings with developer workflow or deployment context:
- Snyk: Snyk bills Snyk Infrastructure as Code per active contributor across Free, Team, and Enterprise plans, and its Terraform support scans single files.
- Wiz: Wiz Code maps every live resource back to the module, file, line, and author that created it and routes a fix PR to that owner.
- Checkmarx: Checkmarx One’s Cloud Insights traces a vulnerability in a running application back to its repository and developer, then ranks fixes by runtime exposure. Pricing is a custom quote per package.
Each product emphasizes a different handoff between code findings, resource ownership, and deployed workloads.
IaC Scanning Best Practices
Rolling out IaC scanning in a development, security, and operations (DevSecOps) program is mostly a sequencing problem for continuous integration and continuous delivery (CI/CD) pipeline security. If the first enforced run fails every PR with dozens of findings, engineers add blanket suppressions to unblock themselves.
Checkov’s –create-baseline flag records today’s findings in a .checkov.baseline file, and –baseline then reports only new failures, which lets you start in report-only mode with –soft-fail.
A checkov:skip=CHECK_ID:reason comment on a resource records each accepted exception next to the code it covers. Enforcement can then tighten to critical and high findings, using severities with an API key or a list of check IDs without one.
IDE Plugins and Pre-Commit Hooks Give the Fastest Feedback
Snyk, Checkmarx, and Wiz ship VS Code extensions, and Checkov’s pre-commit hooks include a checkov_diff variant that scans only changed files and a secrets-only hook. A developer sees the failed check in the terminal before the PR exists, with no reviewer waiting and no pipeline minutes spent.
Pull Request Checks and Pipeline Gates Enforce Severity Thresholds
Checkov’s –hard-fail-on and –soft-fail-on flags accept check IDs or severities, and with a Prisma Cloud API key, –hard-fail-on HIGH,CRITICAL returns a non-zero exit only for those classes while lower findings still land in the report.
Severity values require an API key. Without one, Checkov ignores severities in these flags, and your gate needs to reference a list of check IDs instead.
The same Checkov command line works as a step in GitHub Actions, Jenkins, and CircleCI, so one gating configuration carries across runners. GitLab ships a Jobs/SAST-IaC.gitlab-ci.yml template that documents no fail-on-severity setting, though its Ultimate tier can feed IaC results into approval workflows. Splitting critical and high findings from lower-severity results also keeps the warning stream from turning into alert fatigue.
Policy as Code Maps Scan Output to Compliance Frameworks
Checkov accepts custom policies in Python or YAML, Trivy and Terrascan take Rego, and Snyk’s custom rules are Rego too. Commercial scanners usually show which policies map to each framework requirement, and keeping policies in the template repository puts compliance changes through the same PR review.
Runtime Drift Monitoring Takes over After Deployment
Drift is the difference between what your templates declare and what is running, and IaC scanning stops seeing it once terraform apply finishes. Manual emergency fixes, legacy resources created before IaC, and automated tools holding write permissions all change infrastructure without touching a template, and a refresh-only Terraform plan spots divergence only in resources Terraform already tracks.
On April 4, 2025, a CircleCI operator changed a Web Application Firewall (WAF) rule by hand while believing they were taking read-only actions. A misconfigured IAM control let that role make changes outside Terraform, and the rule blocked legitimate traffic until automated drift detection surfaced it about 80 minutes later during incident response.
Restricting console write access keeps changes in the pipeline, and cloud security posture management (CSPM) catches the security incident no template contains, such as a port 22 opened from the console.
Pair Pre-Deploy Scanning with Runtime Posture Checks
IaC scanning covers the pre-deployment side, and a separate tool has to watch what happens after the apply. Coralogix CSPM scans live AWS, Azure, and Google Cloud accounts on a schedule, every 24 hours by default, and assesses deployed posture against CIS benchmarks plus PCI DSS and HIPAA frameworks.
Scan results land in Coralogix, where you can filter failed resources in Explore or in custom dashboards. It reads deployed cloud configuration rather than template files, which makes it the runtime counterpart to what Checkov or Snyk flags in a PR.
Cloud SIEM, Coralogix’s security information and event management (SIEM) product, adds in-stream threat detection alongside those posture checks.
Start a free 14-day Coralogix trial to run CSPM against your own cloud accounts. You’ll see deployed misconfigurations in the same place your team already investigates logs and security events.

Frequently Asked Questions About IaC Security Scanning
What Is the Difference Between IaC Scanning and CSPM?
IaC scanning analyzes template files before any resource exists, so it finds problems in code and can name the file and line that introduced them. CSPM inspects resources already running in a cloud account and finds misconfigurations whether they came from a template, a console click, or an automated tool. A scanner can’t detect a console change, and a standalone CSPM scan doesn’t know which template produced a resource unless a code-to-cloud mapping links them.
Can IaC Scanning Detect Secrets Hidden in Template Files?
Checkov detects secrets with regex, keywords, and entropy, and its –scan-secrets-history flag checks past commits as well. Trivy matches secrets with keyword-filtered regex rules through trivy fs or trivy repo, since trivy config scans only for misconfigurations. The Gitleaks repository and TruffleHog add dedicated history scanning, and TruffleHog checks whether a found credential is still live. Running a template scanner and a history scanner together, then de-duplicating the results, gives you coverage of current files and past commits.
How Does IaC Scanning Fit into a DevSecOps Pipeline Without Slowing Teams Down?
You can fail the pipeline only on critical and high misconfigurations, report medium as a warning, and route low to a dashboard for batch cleanup. Checkov needs a Prisma Cloud API key to filter by severity, and without one you gate on a list of check IDs. Checks in the IDE and on the PR clear findings before a reviewer sees them, so the merge gate only has to catch what slipped through.
Which IaC Formats Does Scanning Typically Cover?
Every tool in this guide reads Terraform, CloudFormation, and Kubernetes manifests, though Snyk reads Helm only through its Git integration. ARM templates, Bicep, Ansible, and Kustomize vary by tool: Checkov evaluates Bicep directly, Trivy requires converting Bicep to ARM first, and Terrascan lists Kustomize and ARM but not Ansible.