Runs Trivy's misconfiguration scanner (`trivy config`) against IaC directories to detect security issues across Terraform, CloudFormation, Kubernetes manifests, Helm charts, Dockerfiles, and Azure ARM templates - installs Trivy, scans with severity gating via `--exit-code`, suppresses findings via `.trivyignore` / `.trivyignore.yaml` or inline annotations, extends built-in checks with custom Rego policies, and emits SARIF for GitHub Code Scanning. Trivy is the forward path from tfsec (per Aqua Security's own migration guidance). Use when adopting a consolidated IaC scanner for new projects, migrating away from tfsec, or scanning mixed IaC stacks with a single tool.
79
99%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Medium
Suggest reviewing before use
Trivy is Aqua Security's consolidated misconfiguration scanner (trivy config) and the forward path from tfsec. Per the tfsec skill,
trivy.dev misconfiguration docs, and Aqua's own documentation, new
projects should evaluate Trivy first; tfsec's checks ship inside Trivy
under trivy config.
Bump these together when updating; they are the only version-sensitive
tokens in this skill. GitHub release assets are version-stamped, so the
RPM URL in Step 1 pins a tag rather than using latest/download.
| Component | Pin | Used in |
|---|---|---|
| Trivy | v0.72.0 (latest as of 2026-06-30) | Step 1 install |
aquasecurity/trivy-action | 0.31.0 | CI workflow (Step 7) |
actions/checkout | v5 | CI workflow (Step 7) |
github/codeql-action/upload-sarif | v3 | CI workflow (Step 7) |
Per trivy.dev installation docs (the RPM URL pins the Trivy tag from the Pinned versions section above):
# macOS
brew install trivy
# Debian / Ubuntu
sudo apt-get install wget apt-transport-https gnupg
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key \
| gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] \
https://aquasecurity.github.io/trivy-repo/deb generic main" \
| sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy
# RPM (RHEL / Fedora)
sudo rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.72.0/trivy_0.72.0_Linux-64bit.rpm
# Docker (no local install)
docker run --rm -v $(pwd):/workspace aquasec/trivy config /workspaceVerify: trivy --version.
Per cli reference, trivy config accepts a path (file or
directory). Trivy auto-detects IaC types - Terraform, CloudFormation,
Kubernetes manifests, Helm charts, Dockerfiles, and Azure ARM templates
can all coexist in the same directory per mc docs.
# Scan the current directory (all IaC types)
trivy config .
# Scan a specific subdirectory
trivy config ./infra/
# Show only HIGH and CRITICAL findings
trivy config --severity HIGH,CRITICAL .
# Fail CI when any finding is found (exit code 1)
trivy config --exit-code 1 --severity HIGH,CRITICAL .
# Include passed checks alongside failures
trivy config --include-non-failures .Built-in checks are distributed as an OPA bundle at
ghcr.io/aquasecurity/trivy-checks (per checks repo).
Trivy caches the bundle locally and refreshes every 24 hours. An
embedded fallback is included in the binary for air-gapped environments.
Per cli reference, --exit-code and --severity are the two
levers for CI gating:
| Flag | Purpose | Example |
|---|---|---|
--exit-code int | Exit code when findings match | --exit-code 1 |
--severity strings | Comma-separated severity filter | HIGH,CRITICAL |
Pattern: gate hard on CRITICAL first; expand to HIGH after the
team has reviewed the initial finding set.
# Hard fail on CRITICAL only (bootstrap phase)
trivy config --exit-code 1 --severity CRITICAL .
# Ratchet: add HIGH once existing findings are triaged
trivy config --exit-code 1 --severity HIGH,CRITICAL .Per trivy.dev reporting docs, --format accepts:
| Value | Use case |
|---|---|
table (default) | Human-readable terminal output |
json | Machine-parseable; pipe to jq |
sarif | GitHub Code Scanning / SARIF 2.1.0 |
template | Custom templates (JUnit, ASFF, HTML via contrib/) |
# JSON for parsing / badge generation
trivy config --format json --output trivy.json .
# SARIF for GitHub Code Scanning
trivy config --format sarif --output trivy.sarif .
# JUnit XML for CI test reporting
trivy config --format template \
--template "@contrib/junit.tpl" \
--output trivy-junit.xml .# .trivyignore
# Suppress a specific misconfig check
AVD-DS-0002
# Suppress a CVE alongside a misconfig in the same file
CVE-2018-14618Per filter docs, the YAML variant supports scoped expiring suppressions:
# .trivyignore.yaml
misconfigurations:
- id: AVD-DS-0001
- id: AVD-DS-0002
paths:
- "infra/legacy/Dockerfile"
statement: "Legacy image; migration tracked in JIRA-4321"
expired_at: "2026-12-31"Run with: trivy config --ignorefile ./.trivyignore.yaml .
Per cli reference, --ignorefile defaults to .trivyignore and
accepts an alternate path.
Per filter docs, pass --ignore-policy with a Rego file that
contains a trivy package and an ignore rule:
# ignore_legacy.rego
package trivy
default ignore = false
ignore {
input.Type == "terraform"
input.Namespace == "user.legacy"
}trivy config --ignore-policy ignore_legacy.rego .Per trivy.dev custom checks docs, pass custom policies with
--config-check and scope them with --namespaces:
trivy config \
--config-check ./policies/ \
--namespaces user \
./infra/Per custom docs, the --namespaces value (here: user) must
match the first segment of the package path. For a full policy file
(METADATA block + deny rule) and the list of supported
input.selector types, see
references/trivy-config.md.
Per trivy.dev reporting docs, SARIF output integrates directly
with GitHub Code Scanning. For the full GitHub Actions workflow (with
security-events: write, the pinned trivy-action, and an
if: always() SARIF upload so findings surface even when the scan exits
non-zero), see references/trivy-config.md.
To scope the scan to a single IaC type, pass --misconfig-scanners per
cli reference:
# Terraform only
trivy config \
--misconfig-scanners terraform \
./terraform/
# Kubernetes manifests only
trivy config \
--misconfig-scanners kubernetes \
./k8s/Per cli reference, --misconfig-scanners accepts a
comma-separated list from: azure-arm, cloudformation, dockerfile,
helm, kubernetes, terraform, terraformplan-json,
terraformplan-snapshot.
| Anti-pattern | Why it fails | Fix |
|---|---|---|
--exit-code 0 in CI | Misconfigs are logged but never block | Use --exit-code 1 with --severity HIGH,CRITICAL (Step 3) |
.trivyignore entries without a statement | Invisible to reviewers; silent security debt | Use .trivyignore.yaml with statement + expired_at (Step 5) |
Running trivy config and tfsec in parallel without a unifier | Duplicate findings flood CI output | Route both through a single unifying reporter |
| Custom policies missing METADATA block | No severity, no title in report output | Always include METADATA with id, severity, schemas (Step 6) |
Skipping bundle updates (--skip-check-update) permanently | Stale checks miss new misconfig rules | Use for caching in CI; re-enable updates on a scheduled run |
ghcr.io/aquasecurity/trivy-checks. Air-gapped setups need the
embedded binary fallback or a mirror.--tf-vars to reduce
noise per cli reference.--helm-values for
accurate rendering of templated manifests per cli reference.schema["cloud"] will not fire against Kubernetes manifests; use the
correct selector type per custom docs..rpm release package, container image.trivy config CLI reference: --exit-code,
--severity, --format, --output, --ignorefile,
--config-check, --namespaces, --misconfig-scanners,
--tf-vars, --helm-values, --cf-params, --include-non-failures.title, description, schemas, custom.id, custom.severity,
custom.input.selector.type), deny rule pattern, --namespaces
scoping..trivyignore and .trivyignore.yaml suppression
format (id, paths, statement, expired_at), --ignore-policy
Rego-based filtering.table, json, sarif,
template; --output flag; SARIF 2.1.0 compliance.aquasecurity/trivy-checks - the upstream
OPA bundle for all built-in checks.tfsec-policy - Migration context: tfsec is transitioning
to Trivy; this skill is the forward path.checkov-policy - Sister scanner;
broader Python-check framework, different rule coverage.