tfsec-policy
Configures tfsec for Terraform-specific security scanning - covers AWS / Azure / GCP / Kubernetes / OpenStack / Oracle / DigitalOcean / CloudStack, custom YAML rules, and SARIF / JUnit / Markdown output. Note: tfsec is transitioning to Trivy per Aqua Security, so new projects evaluate that first. Use for an existing Terraform-only tfsec stack; for the consolidated forward-path scanner use trivy-config, for the broadest multi-framework checks use checkov-policy, and for wider platform breadth use kics-policy.
Install with skills.sh (any agent)
npx skills add testland/qa --skill tfsec-policytfsec-policy
Overview
Per tfsec-home (opens in new window), tfsec is transitioning to Trivy, Aqua Security's consolidated scanner. For new projects, evaluate Trivy first; tfsec remains stable for existing usage.
When to use
How to use
Step 1 - Install
# macOS
brew install tfsec
# Linux
curl -L https://github.com/aquasecurity/tfsec/releases/latest/download/tfsec-linux-amd64 \
-o /usr/local/bin/tfsec
chmod +x /usr/local/bin/tfsecStep 2 - Run
# Scan current directory
tfsec .
# Scan specific path
tfsec ./terraform/
# Concise output
tfsec . --concise-output
# Specific severity threshold
tfsec . --minimum-severity HIGHStep 3 - Output formats
Per tfsec-home (opens in new window): "JSON and SARIF output capabilities for integration with external tools and workflows."
# JSON
tfsec . -f json > tfsec.json
# SARIF (GitHub Code Scanning)
tfsec . -f sarif -O tfsec.sarif
# JUnit XML
tfsec . -f junit -O tfsec.xml
# Markdown (PR comments)
tfsec . -f markdownStep 4 - Skip checks
# Skip specific checks
tfsec . -e aws-s3-enable-bucket-encryption,aws-s3-enable-versioning
# Skip everything matching a pattern
tfsec . -e aws-s3-*Inline:
# main.tf
resource "aws_s3_bucket" "public_data" {
# tfsec:ignore:aws-s3-enable-bucket-encryption Public dataset, not encrypted by design
# tfsec:ignore:aws-s3-enable-bucket-logging Public CDN, no audit logging needed
bucket = "my-public-data"
acl = "public-read"
}Step 5 - Custom rules
Author custom YAML rules for team-specific policy the built-in set misses: references/custom-rules-and-ci.md.
Step 6 - CI integration
Run the official tfsec action with SARIF upload to GitHub Code Scanning: references/custom-rules-and-ci.md.
Step 7 - Supported clouds
Per tfsec-home (opens in new window), tfsec covers AWS (S3, EC2, RDS, IAM, Lambda, API Gateway, and 30+ services), Azure (App Service, Storage, Database, Container, Key Vault), Google Cloud (Compute, GKE, SQL, Storage, IAM, BigQuery), plus Kubernetes, OpenStack, Oracle, DigitalOcean, and CloudStack.
For unsupported clouds, fall back to OPA / Conftest with custom Rego per policy-as-code-runner.
Step 8 - Migration to Trivy
Per tfsec-home (opens in new window) guidance:
# Install Trivy
brew install trivy # or apt-get / etc.
# Trivy includes tfsec's checks under `trivy config`
trivy config ./terraform/The migration is mostly mechanical - Trivy ingests the same .tf files; rule names may differ.
Step 9 - Combine with Checkov + KICS
Multiple scanners catch overlapping but non-identical issues. tfsec is faster and Terraform-specific; Checkov is broader; KICS adds different rule classes.
tfsec . -f json > tfsec.json
checkov -d . -o json > checkov.json
kics scan -p . --report-formats json
# unify results across the three scannersWorked example
A team runs tfsec on an AWS Terraform module while planning a Trivy migration.
Result: HIGH-severity misconfigurations gate the build, intentional exceptions are documented inline, and the Trivy forward-path is validated before switching.
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Starting new tfsec adoption in 2026+ without Trivy evaluation | Investing in deprecating path. | Evaluate Trivy first (Step 8). |
tfsec:ignore without justification comment | Skips invisible to reviewers; security debt. | Always include reason (Step 4 example). |
--minimum-severity LOW everywhere | Noise floods CI; team disables. | Start HIGH; ratchet down. |
| Custom rules without tests | Bugs in custom rules let bad config through. | Cross-reference with OPA-tested policies (Step 5 + Conftest). |
| Single-scanner approach | Tool-specific gaps. | Multiple scanners (Step 9). |
Limitations
References
tfsec custom rules and CI integration
View source (opens in new window)tfsec custom rules and CI integration
Custom rules
# .tfsec/custom_checks.yml
checks:
- code: CUS001
description: Ensure all EC2 instances have a cost_center tag
impact: Untagged resources cannot be allocated to cost centers
resolution: Add a cost_center tag
requiredTypes:
- resource
requiredLabels:
- aws_instance
severity: HIGH
matchSpec:
name: tags
action: contains
value: cost_center
errorMessage: EC2 instance is missing cost_center tagCI integration
jobs:
tfsec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: aquasecurity/tfsec-action@v1.0.3
with:
additional_args: --minimum-severity HIGH
format: sarif
output_file_path: tfsec.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: tfsec.sarifRelated skills
checkov-policy
Configures Checkov for IaC security scanning across Terraform, CloudFormation, Kubernetes, Helm, ARM, Serverless, AWS CDK - `pip install checkov`, custom Python checks, SARIF / JUnit output, and `--baseline` gating so CI fails only on new findings in legacy code. Use for the broadest built-in rule set with Python custom checks; for Terraform-only scanning use tfsec-policy, for wider platform breadth (OpenAPI / Pulumi / Crossplane) use kics-policy, and for a consolidated new-project scanner use trivy-config.
helm-chart-tester
Configures helm-unittest for Helm chart unit testing - installs the `helm-unittest` plugin, authors `tests/*.yaml` per template, asserts on rendered manifests (`isKind`, `equal`, `matchRegex`, snapshots), plus `helm lint` and `helm template` render testing. Use to verify a chart's template logic and rendered shape; this is unit-level correctness testing, not security scanning - to enforce policy on rendered manifests use policy-as-code-runner, and to scan charts for misconfigurations use checkov-policy or kics-policy.
kics-policy
Configures KICS (Keeping Infrastructure as Code Secure), Checkmarx's scanner covering Terraform, Kubernetes, Helm, Dockerfile, OpenAPI, Ansible, ARM, CloudFormation, Pulumi, Crossplane - CLI / Docker / GitHub Action / pre-commit, JSON / SARIF / HTML / JUnit output, custom Rego queries. Use for the widest platform breadth, especially OpenAPI / Pulumi / Crossplane; for the broadest built-in checks with Python custom rules use checkov-policy, for Terraform-only scanning use tfsec-policy, and for a consolidated scanner use trivy-config.
policy-as-code-runner
Configures policy-as-code testing using OPA / Conftest / Cedar - authors policies in Rego (OPA's language), runs Conftest against Kubernetes manifests / Terraform plans / Dockerfiles / arbitrary structured data, integrates with CI for PR-time policy gates. Per OPA's docs: "an open source, general-purpose policy engine that unifies policy enforcement across the stack." Use to express + enforce custom policies (cost limits, tagging requirements, security baselines) that Checkov / tfsec / KICS don't cover.
trivy-config
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.