Open-Source Wikis

/

Trivy

/

Features

/

IaC scanning

aquasecurity/trivy

IaC scanning

Active contributors: Owen Rumney, nikpivkin, knqyf263

Purpose

This page is the deep dive on the IaC engine itself: how parsers turn HCL/JSON/YAML into normalized provider models, how the Rego engine evaluates rules against those models, and how the result is turned into Misconfiguration findings. The user-facing feature is described in misconfiguration scanning; this page focuses on the internals.

The IaC engine in pkg/iac/ originated as the tfsec and defsec projects, which were folded into Trivy in 2022. It is the largest single subsystem in the repo (~91,000 Go lines).

Directory layout

pkg/iac/
├── adapters/       # per-format → provider-state adapters
├── detection/      # file-format detectors (HCL, JSON, YAML, ARM, Bicep, ...)
├── framework/      # rule namespaces and bundling
├── ignore/         # in-source ignore comments (`# trivy:ignore:AVD-...`)
├── providers/      # normalized cloud resource models
├── rego/           # Rego host: scanner, embed, custom-rule loader
├── rules/          # built-in (non-Rego) check helpers
├── scan/           # `Scan` entry point that aggregates parsers + Rego
├── scanners/       # per-format scanners (terraform, cloudformation, k8s, helm, ...)
├── severity/       # severity normalization
├── state/          # State / overall-result types
├── terraform/      # Terraform-specific shared types
└── types/          # shared types (Resource, Range, Metadata, ...)

How a Terraform scan flows

sequenceDiagram
    participant Misconf as pkg/misconf
    participant TF as pkg/iac/scanners/terraform
    participant Parser as terraform parser
    participant Adapter as adapters/terraform
    participant Providers as pkg/iac/providers/aws/...
    participant Rego as pkg/iac/rego
    participant Bundle as Trivy Checks bundle

    Misconf->>TF: Scan(fs, options)
    TF->>Parser: ParseFS(.)
    Parser-->>TF: Module tree
    TF->>Adapter: Adapt(modules)
    Adapter->>Providers: build Provider state (S3, IAM, ...)
    Adapter-->>TF: state.State
    TF->>Rego: Scan(state)
    Rego->>Bundle: load policies
    Rego-->>TF: scan.Results
    TF-->>Misconf: Misconfigurations

Other formats follow the same shape with their own parser and adapter; the Rego engine and provider state are shared.

Provider state

The state model in pkg/iac/state/state.go holds normalized resource lists per cloud. For example, state.AWS.S3.Buckets is a slice of aws.S3.Bucket regardless of whether the source was Terraform, CloudFormation, or Pulumi. Each resource carries its own Metadata (file path, line range, originating module) so findings can point back to source.

Adapters

Each (format, cloud) pair has an adapter under pkg/iac/adapters/<cloud>/<format>/ that maps parsed format-specific resources to the normalized provider shape. AWS has the most adapters because every Terraform AWS service has its own file. The adapter pattern is what made it tractable to share rules across Terraform, CloudFormation, and Helm.

Rego runtime

pkg/iac/rego/scanner.go wraps OPA's Go bindings. At init it:

  1. Loads the embedded built-in rules from pkg/iac/rego/embed.go.
  2. Optionally loads user-supplied rules from --config-policy <dir>.
  3. Optionally loads JSON data from --config-data.
  4. Scans the provider state, evaluating each rule against the relevant subset of resources.

Rule metadata (severity, AVD ID, title, description, remediation) lives next to the Rego file in YAML; Trivy reads both at load time.

File-format detection

pkg/iac/detection/ decides which scanner to dispatch for a given file. It uses heuristics — first line, file extension, top-level keys — rather than full parsing, because the dispatcher runs on every file the walker visits. The detection types are defined in pkg/iac/detection/detect.go (FileTypeTerraform, FileTypeCloudFormation, FileTypeKubernetes, FileTypeHelm, FileTypeDockerfile, FileTypeAnsible, FileTypeAzureARM, FileTypeBicep, FileTypeYAML, FileTypeJSON).

Helm and ARM peculiarities

  • Helm scans both the chart sources and the rendered output. The Helm scanner renders templates with default values, then dispatches the rendered Kubernetes manifests through the Kubernetes scanner.
  • Azure ARM/Bicep has a Bicep-to-ARM JSON pre-pass; the rest mirrors Terraform/CloudFormation.

Ignores

pkg/iac/ignore/ understands inline ignore comments (# trivy:ignore:AVD-AWS-0001, // trivy:ignore:AVD-DS-0001 expiry: 2025-01-01) and the --ignorefile (a global list of CVE/AVD IDs). Ignores carry an optional expiry date.

Performance

Two settings affect performance significantly:

  • --rego-include-deprecated-checks — adds a few hundred extra rules.
  • --config-trace — enables Rego tracing (slows scans by 10x or more; for debugging only).

For very large Terraform repositories, consider --terraform-exclude-downloaded-modules to skip remote modules.

Integration points

Entry points for modification

  • New parserpkg/iac/scanners/<format>/. Implement the Scanner interface (Scan(fs)).
  • New cloud service — extend pkg/iac/state/state.go with the new top-level field, add the resource shape under pkg/iac/providers/<cloud>/<service>/, then add adapters.
  • Tune Regopkg/iac/rego/scanner.go is the primary surface.
  • Add a metadata field on findingspkg/iac/types/metadata.go and the renderers.

Key source files

File Purpose
pkg/iac/scan/scanner.go High-level Scan orchestrator.
pkg/iac/scanners/terraform/parser/parser.go HCL parser entry.
pkg/iac/scanners/cloudformation/parser/ CloudFormation parser.
pkg/iac/scanners/kubernetes/parser/ Kubernetes manifest parser.
pkg/iac/scanners/helm/parser/ Helm chart parser.
pkg/iac/scanners/dockerfile/parser/ Dockerfile parser.
pkg/iac/scanners/ansible/parser/ Ansible parser.
pkg/iac/scanners/azure/parser/ ARM/Bicep parser.
pkg/iac/state/state.go Provider state aggregate.
pkg/iac/rego/scanner.go Rego host.
pkg/iac/rego/embed.go Embedded built-in rules.
pkg/iac/ignore/ In-source ignore comments.
pkg/iac/detection/detect.go File-format heuristics.

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

IaC scanning – Trivy wiki | Factory