tfsec-policy
Configures tfsec for Terraform-specific security scanning - covers AWS / Azure / GCP / Kubernetes / OpenStack / Oracle / DigitalOcean / CloudStack with developer-friendly output. Important: tfsec is **transitioning to Trivy** per Aqua Security''''s positioning; new projects evaluate Trivy first. For existing tfsec users, this skill covers config + custom rules + CI integration. Use for Terraform-only projects mid-transition or where tfsec''''s specific check coverage matters.
tfsec-policy
Overview
Important migration note per tfsec-home:
"tfsec is transitioning to Trivy, Aqua Security's consolidated scanning solution. The project documentation notes: 'Going forward we want to encourage the tfsec community to transition over to Trivy.'"
For new projects: evaluate Trivy first. tfsec remains stable for existing usage.
When 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: "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
# .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 tagStep 6 - CI 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.sarifStep 7 - Supported clouds
Per tfsec-home:
"AWS: API Gateway, EC2, S3, RDS, IAM, Lambda, and 30+ additional services
Azure: App Service, Storage, Database, Container, Key Vault, and others
Google Cloud: Compute, GKE, SQL, Storage, IAM, BigQuery, and more
Additional support includes Kubernetes, OpenStack, Oracle, DigitalOcean, and CloudStack environments."
For unsupported clouds, fall back to OPA / Conftest with custom Rego per policy-as-code-runner.
Step 8 - Migration to Trivy
Per tfsec-home 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
Per iac-policy-checker: 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
# iac-policy-checker agent unifies resultsAnti-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). |