TL;DR

  • Compliance scanning should happen in CI before deployment, not during annual audits
  • Checkov, KICS, and Trivy provide pre-built policies mapped to SOC2, HIPAA, PCI-DSS, and CIS benchmarks
  • The #1 mistake: running compliance tools manually instead of as automated CI gates

Best for: Teams in regulated industries (healthcare, finance) or pursuing SOC2 certification Skip if: You’re building internal tools with no compliance requirements Read time: 10 minutes

Your SOC2 auditor asks for evidence that all S3 buckets have encryption enabled. You spend three days pulling CloudTrail logs, cross-referencing with Terraform state, and building a spreadsheet. Next quarter, they ask again. And again.

This is compliance theater — reactive evidence gathering instead of proactive enforcement. In 2026, compliance-as-code means your infrastructure can’t be deployed unless it meets the controls. The audit evidence is your CI pipeline history.

The Real Problem

Traditional compliance approaches fail for IaC because they’re designed for static environments. An auditor reviews your AWS console once a year. But your Terraform deploys 50 times a day. By the time the audit happens, the infrastructure has changed thousands of times.

The shift-left approach means:

  • Compliance checks run on every pull request
  • Non-compliant resources can’t be deployed (not just flagged)
  • Evidence is automatically generated and stored
  • Drift from compliant state triggers alerts

This isn’t about passing audits faster — it’s about being continuously compliant rather than point-in-time compliant.

IaC Compliance Scanning Tools

Three open-source tools dominate IaC compliance scanning in 2026:

ToolMaintainerFrameworksKey Strength
CheckovPalo Alto NetworksTerraform, CloudFormation, K8s, ARMPre-built SOC2/HIPAA/PCI mappings
KICSCheckmarx15+ IaC formatsQuery-based customization
TrivyAqua SecurityIaC + containers + SBOMUnified scanning pipeline

All three support CIS Benchmarks, but Checkov has the most explicit compliance framework mappings out of the box.

Checkov for Compliance

Checkov’s built-in policies map directly to compliance standards. Running a SOC2-focused scan:

# Scan Terraform directory for SOC2-relevant checks
checkov -d ./terraform --framework terraform --check CKV_AWS_19,CKV_AWS_20,CKV_AWS_21

# Or use the compliance framework filter
checkov -d ./terraform --compliance-framework soc2

# Output as JUnit XML for CI integration
checkov -d ./terraform -o junitxml > compliance-report.xml

The key insight is that Checkov maps checks to specific compliance controls:

CKV_AWS_19 → SOC2 CC6.1 (Encryption at rest)
CKV_AWS_20 → SOC2 CC6.6 (S3 public access)
CKV_AWS_21 → HIPAA 164.312(e)(2) (Encryption in transit)

Notice how a single resource can satisfy multiple frameworks. Your S3 encryption check covers SOC2, HIPAA, and PCI-DSS simultaneously.

Custom Compliance Policies

Pre-built policies cover common cases, but your organization likely has specific requirements. Checkov supports custom policies in Python or YAML:

# custom_policies/require_cost_center_tag.yaml
metadata:
  id: "CUSTOM_AWS_1"
  name: "Ensure all resources have cost_center tag"
  category: "GOVERNANCE"
  guideline: "All resources must have cost_center tag for billing attribution"

definition:
  cond_type: "attribute"
  resource_types:

    - "aws_instance"
    - "aws_s3_bucket"
    - "aws_rds_instance"
  attribute: "tags.cost_center"
  operator: "exists"

Run with your custom policy directory:

checkov -d ./terraform --external-checks-dir ./custom_policies

For complex logic, Python policies offer more flexibility:

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

class RequireApprovedAMI(BaseResourceCheck):
    def __init__(self):
        name = "Ensure EC2 uses approved AMI from internal registry"
        id = "CUSTOM_AWS_2"
        supported_resources = ["aws_instance"]
        categories = [CheckCategories.GENERAL_SECURITY]
        super().__init__(name=name, id=id, categories=categories,
                        supported_resources=supported_resources)

    def scan_resource_conf(self, conf):
        ami = conf.get("ami", [""])[0]
        approved_prefixes = ["ami-internal-", "ami-approved-"]

        if any(ami.startswith(prefix) for prefix in approved_prefixes):
            return CheckResult.PASSED
        return CheckResult.FAILED

check = RequireApprovedAMI()

CI/CD Integration

Compliance scanning must block deployments, not just report. Here’s a GitHub Actions workflow:

name: Compliance Gate

on:
  pull_request:
    paths:

      - 'terraform/**'

jobs:
  compliance-scan:
    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@v4

      - name: Run Checkov
        uses: bridgecrewio/checkov-action@v12
        with:
          directory: terraform/
          framework: terraform
          output_format: cli,sarif
          output_file_path: console,results.sarif
          soft_fail: false  # Fail the build on violations
          skip_check: CKV_AWS_999  # Known exception

      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

The soft_fail: false is critical — it ensures non-compliant PRs cannot merge.

Mapping Controls to Evidence

Auditors need evidence, not tool output. Create a compliance matrix that maps your CI checks to specific controls:

Control IDRequirementToolCheck IDEvidence Location
SOC2 CC6.1Encryption at restCheckovCKV_AWS_19GitHub Actions logs
HIPAA 164.312(a)(1)Access controlsCheckovCKV_AWS_40GitHub Actions logs
PCI-DSS 3.4Stored cardholder dataCustomCUSTOM_PCI_1Artifact storage

Store compliance scan results as build artifacts with retention matching your audit cycle (typically 1-3 years for SOC2).

AI-Assisted Approaches

Writing custom compliance policies requires understanding both the regulation and the IaC resource structure. AI tools excel here.

What AI does well:

  • Translating regulatory text into Checkov/KICS policy rules
  • Identifying which IaC resources are relevant to specific controls
  • Generating test cases for custom policies
  • Explaining why a resource fails a particular check

What still needs humans:

  • Interpreting ambiguous regulatory language
  • Deciding which controls apply to your specific architecture
  • Approving exceptions and documenting compensating controls
  • Reviewing AI-generated policies for correctness

Useful prompt:

I need a Checkov custom policy (Python) that enforces:

- All RDS instances must have deletion_protection enabled
- Exception: instances with tag "environment=development"
- Map to SOC2 control CC6.1 (logical access controls)
Include unit tests using pytest

When This Breaks Down

Compliance scanning has limitations:

False sense of security: Passing all checks doesn’t mean you’re secure. Compliance frameworks are minimum baselines, not comprehensive security.

Tool coverage gaps: No scanner covers every resource type. New AWS services might not have policies for months.

Runtime vs deploy-time: These tools check what will be deployed, not what’s currently running. A manually-modified resource bypasses all gates.

Exception management: Every organization accumulates exceptions. Without governance, your “compliant” state becomes Swiss cheese.

Consider complementary approaches:

  • Policy as Code with OPA/Sentinel for custom enforcement
  • AWS Config / Azure Policy for runtime compliance
  • Cloud Security Posture Management (CSPM) for continuous monitoring

Decision Framework

Use Checkov when:

  • You need explicit SOC2/HIPAA/PCI mappings
  • Python-based custom policies fit your team’s skills
  • You want the largest pre-built policy library

Use KICS when:

  • You need maximum IaC format coverage (15+ formats)
  • Query-based customization matches your workflow
  • You’re already using Checkmarx for SAST

Use Trivy when:

  • You want unified container + IaC scanning
  • SBOM generation is required
  • You’re in a Kubernetes-heavy environment

Measuring Success

MetricBeforeAfterHow to Track
Audit prep time2-3 weeks1-2 daysHours logged
Compliance violations in prodUnknown0CSPM dashboard
Time to remediate findingDaysHoursPR merge timestamps
Policy coverage0%90%+ resourcesCheckov –list

Warning signs it’s not working:

  • Teams requesting too many exceptions
  • Compliance scans taking >10 minutes (blocking velocity)
  • Auditors rejecting CI logs as evidence
  • Scan results ignored because of noise

What’s Next

Start with one compliance framework. If you’re pursuing SOC2:

  1. Run checkov -d ./terraform --compliance-framework soc2 --list to see applicable checks
  2. Enable the top 10 highest-severity checks as blocking
  3. Document exceptions with compensating controls
  4. Gradually expand coverage each sprint
  5. Present CI pipeline as audit evidence trail

The goal is making compliance a side effect of good engineering practices, not a separate workstream.


Related articles:

External resources:

Official Resources

See Also