With Trivy 0.74, how do you scan a folder of Terraform, Kubernetes and Dockerfiles for misconfigurations, and how do you read one finding?
answer
- one subcommand, one scanner
- file type detected per file
- Tests line: successes and failures
- ID, severity, AVD link, file lines
- other subcommands leave it off
basics
~20 sRun trivy config on the folder; it detects each file's type and applies the built-in trivy-checks bundle. Each failure gives severity, check ID, title, an AVD link and file lines. fs, image and repo skip this unless --scanners misconfig is set.
solid answer
~40 s`trivy config ./iac` (alias `trivy conf`) runs only the misconfiguration scanner. It walks the tree, detects each file's config type (Terraform, CloudFormation, Kubernetes, Helm, Dockerfile, Azure ARM, Ansible) and evaluates the matching checks from the trivy-checks bundle. Each file gets a header such as `main.tf (terraform)` and a line like `Tests: 23 (SUCCESSES: 14, FAILURES: 9)`, then one block per failure: severity and title, a description, the check's `avd.aquasec.com` link and the `file:start-end` lines. In JSON the same finding carries `ID`, `Severity`, `Message`, `Resolution` and `PrimaryURL`. The trap is the other subcommands: `trivy fs`, `image` and `repo` default to `--scanners vuln,secret`, so a repository full of Terraform shows no misconfigurations until you add `misconfig`. And `--exit-code` defaults to 0, so findings alone do not fail a job.
code
bash · 5 linestrivy config ./infra
trivy config --misconfig-scanners terraform,dockerfile --severity HIGH,CRITICAL ./infra
trivy fs --scanners vuln,secret,misconfig --format json --output report.json .go deeper
Know the command, trivy config on a directory, and be able to point at the four parts of a finding: severity, check ID, AVD link and the file lines.
Explain type detection, the default --misconfig-scanners list, and why fs, repo and image need --scanners misconfig before they report any IaC finding.
Show you can prove a scan evaluated what you think: the Tests line, --include-non-failures, Helm values, image config versus files inside the image.
Frame a scanner whose silent defaults decide coverage: which scanners, types and severities an organisation's shared invocation pins, and how teams see what was never evaluated.
## What `trivy config` is Trivy is a single binary with several subcommands. `trivy config DIR` (alias `trivy conf`) is the one built for **infrastructure as code (IaC)**: it runs the **misconfiguration scanner** and nothing else, so it never looks up CVEs and never runs the secret rules. A *misconfiguration* here means a setting that is legal but unsafe: a container that may run as root, a storage bucket without logging, a security group open to `0.0.0.0/0`. The checks come from the **trivy-checks bundle**, a library of checks written mostly in Rego (some in Go) that Trivy pulls as an OCI artifact and caches locally. In Trivy 0.74 the default source is `mirror.gcr.io/aquasec/trivy-checks:2`. ## How Trivy decides what each file is A single folder can hold several IaC formats. Trivy detects the type per file and only applies checks written for that type: | Config type | Files Trivy recognises | |---|---| | Terraform | `*.tf`, `*.tf.json`, `*.tfvars` | | Terraform plan | `tfplan`, `*.tfplan`, plan JSON | | CloudFormation | `*.yml`, `*.yaml`, `*.json` with a template shape | | Kubernetes | `*.yml`, `*.yaml`, `*.json` with a manifest shape | | Helm | chart directories and packaged charts, rendered to manifests first | | Dockerfile | `Dockerfile`, `Containerfile`, `Dockerfile.prod`, `api.dockerfile` | The `--misconfig-scanners` flag lists which type scanners run. Its 0.74 default is `azure-arm, cloudformation, dockerfile, helm, kubernetes, terraform, terraformplan-json, terraformplan-snapshot, ansible`. Generic `json` and `yaml` are deliberately missing, because no built-in check targets arbitrary JSON or YAML. A file whose name the detector does not recognise, such as `production.docker`, is only scanned if you map it with `--file-patterns "dockerfile:..."`. ## Reading the table report For each detected file the default table output shows: 1. A header naming the file and its detected type, for example `deployment.yaml (kubernetes)`. 2. A `Tests:` line: how many checks applied to that file, how many passed and how many failed. 3. A `Failures:` line counting failures by severity (`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). 4. One block per failure: severity and message, a description, `See https://avd.aquasec.com/misconfig/...`, and the file with the line range that caused it, plus the offending lines. Passing checks are hidden. `--include-non-failures` adds them, which is useful when you need evidence that a control was actually evaluated. ## The same finding in JSON With `--format json`, each result has a `Misconfigurations` array. The fields you read most are: - `ID`: the check identifier; in 0.74 output it reads like `DS-0002` or `KSV-0001`, and the older `AVDID` field is marked deprecated in favour of `ID`. - `Title`, `Message` and `Description`: what the check tests and what it found here. - `Severity` and `Status` (`FAIL`, or `PASS` once `--include-non-failures` is set). - `Resolution`: the fix the check author suggests. - `PrimaryURL` and `References`: the AVD page and upstream guidance. - `CauseMetadata`: provider, service and the resource and lines involved. ## Why another subcommand shows nothing This is the question behind most "Trivy found nothing" surprises: - `trivy fs`, `trivy repo` and `trivy image` default to `--scanners vuln,secret`. Misconfiguration scanning is **off** until you pass `--scanners vuln,secret,misconfig` (or just `misconfig`). - `trivy image --scanners misconfig` checks IaC files that sit *inside* the image's filesystem. Checking the image's own configuration, converted back into a Dockerfile, is a separate opt-in: `--image-config-scanners misconfig`. - `trivy config` has no `--scanners` flag and never runs the secret rules, so it cannot replace a secret scan. - `--severity` defaults to all five levels, so it hides nothing unless someone narrowed it on the command line or in `trivy.yaml`. ## Narrowing the scan - `--misconfig-scanners terraform,dockerfile` restricts the run to those types. - `--severity HIGH,CRITICAL` trims the report to what a team will act on first. - `--exit-code 1` makes findings fail the process; without it Trivy exits 0 even with failures, which matters as soon as the scan becomes a pipeline gate. ## Inputs that change what gets evaluated The same folder can produce different findings depending on the values Trivy renders it with: - **Helm**: the chart is rendered with its own `values.yaml` unless you pass `--helm-values`, `--helm-set`, `--helm-set-string` or `--helm-set-file`; `--helm-kube-version` and `--helm-api-versions` set the capabilities a template may test. - **Terraform**: variable values come from defaults, `TF_VAR_` variables and files named with `--tf-vars`. - **CloudFormation**: parameter files are passed with `--cf-params`. - **Scope**: `--skip-dirs` and `--skip-files` remove paths; anything skipped is simply never evaluated, so keep those lists short and reviewed. A clean report is only as good as the inputs it was rendered with, which is why experienced reviewers ask for the exact command line before they trust one.
- A Helm chart passes trivy config, but the rendered production release runs as root. How can both be true?Trivy renders the chart with its own `values.yaml` before running the Kubernetes checks. If production overrides `securityContext` through another values file or `--set`, the scan evaluated a different manifest. Pass the same overrides with `--helm-values` or `--helm-set` so Trivy renders what you actually deploy.
- Why does a plain YAML settings file produce no findings even when you know it is wrong?It is detected as generic YAML, and `json` and `yaml` are left out of the default `--misconfig-scanners` list because no built-in check targets them. Enabling `yaml` only helps with a custom check that understands the file.
saying these in an interview costs you the question
- trivy fs checks Terraform for misconfigurations by default
- trivy config also reports leaked secrets in the same run
- A finding without its check ID and file lines is enough to act on
- Trivy exits non-zero on any misconfiguration without extra flags
- trivy image --scanners misconfig audits the image's own Dockerfile settings