<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: auditing-terraform-security
description: >-
  Audit Terraform configurations and state for security misconfigurations, hardcoded
  secrets, overly permissive IAM, and infrastructure drift using static analysis tools.
domain: cybersecurity
subdomain: cloud-security
tags:
  - terraform
  - iac-security
  - tfsec
  - checkov
  - static-analysis
  - secrets-detection
  - drift-detection
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1195.002"]
---

# Auditing Terraform Security

## Overview

Infrastructure as Code (IaC) security shifts left by catching misconfigurations before
deployment. This skill covers auditing Terraform HCL files and state for security issues:
hardcoded secrets, overly permissive IAM policies, unencrypted resources, public access
misconfigurations, and infrastructure drift from desired state.

Mode: `[MODE: BLUE]` — Preventive security through IaC analysis.

## Prerequisites

- Terraform v1.0+ installed
- Static analysis tools: `tfsec`, `checkov`, or `trivy config`
- Secret scanning: `gitleaks` or `trufflehog`
- Python 3.10+ for custom rule analysis
- Access to Terraform state (local or remote backend)

## Key Concepts

### Static Analysis with tfsec

```bash
# Install tfsec
brew install tfsec  # macOS
# or: curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash

# Run full scan
tfsec . --format json --out /tmp/tfsec_results.json

# Run with specific severity threshold
tfsec . --minimum-severity HIGH

# Run against specific checks
tfsec . --run-check-ids aws-s3-enable-bucket-encryption,aws-iam-no-policy-wildcards
```

### Checkov Scanning

```bash
# Install checkov
pip install checkov

# Scan Terraform directory
checkov -d . --output json > /tmp/checkov_results.json

# Scan specific framework
checkov -d . --framework terraform --check CKV_AWS_18,CKV_AWS_19,CKV_AWS_21

# Scan Terraform plan
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
checkov -f tfplan.json --framework terraform_plan
```

### Trivy Config Scanning

```bash
# Scan with Trivy
trivy config . --severity HIGH,CRITICAL --format json --output /tmp/trivy_results.json

# Scan specific file
trivy config main.tf
```

### Common Terraform Security Issues

| Issue | CIS Mapping | Tool Check ID |
|-------|------------|---------------|
| S3 bucket without encryption | CIS 2.1.1 | CKV_AWS_19 |
| Security group with 0.0.0.0/0 | CIS 5.2 | CKV_AWS_24 |
| IAM policy with wildcard | CIS 1.16 | CKV_AWS_1 |
| RDS without encryption | CIS 2.3.1 | CKV_AWS_16 |
| CloudTrail not multi-region | CIS 3.1 | CKV_AWS_35 |
| EBS volume unencrypted | CIS 2.2.1 | CKV_AWS_3 |
| Public EC2 instance | — | CKV_AWS_88 |
| Hardcoded secrets in TF | — | CKV_SECRET_* |

### Hardcoded Secrets Detection

```bash
# Scan for secrets in Terraform files
gitleaks detect --source . --report-format json --report-path /tmp/secrets.json

# TruffleHog scan
trufflehog filesystem . --json > /tmp/trufflehog_results.json

# Checkov secret scanning
checkov -d . --framework secrets
```

### Dangerous Terraform Patterns

```hcl
# BAD: Hardcoded credentials
resource "aws_db_instance" "bad" {
  password = "SuperSecret123!"  # NEVER do this
}

# GOOD: Use variables with sensitive flag
variable "db_password" {
  type      = string
  sensitive = true
}

# BAD: Overly permissive IAM
resource "aws_iam_policy" "bad" {
  policy = jsonencode({
    Statement = [{
      Effect   = "Allow"
      Action   = "*"
      Resource = "*"
    }]
  })
}

# BAD: Public S3 bucket
resource "aws_s3_bucket_acl" "bad" {
  bucket = aws_s3_bucket.example.id
  acl    = "public-read"  # Never in production
}
```

### Drift Detection

```bash
# Detect drift between state and actual infrastructure
terraform plan -detailed-exitcode -out=drift.tfplan
# Exit code 2 = drift detected

# Show drift details
terraform show drift.tfplan

# Import unmanaged resources
terraform import aws_security_group.example sg-12345678
```

## Workflow

### Step 1: Run Static Analysis

```bash
node scripts/agent.js --action scan --terraform-dir ./infra/ --output /tmp/tf_audit.json
```

### Step 2: Check for Secrets

```bash
node scripts/agent.js --action secrets --terraform-dir ./infra/ --output /tmp/tf_secrets.json
```

### Step 3: Check Drift

```bash
node scripts/agent.js --action drift --terraform-dir ./infra/ --output /tmp/tf_drift.json
```

### Step 4: Remediate

Fix findings by severity, starting with hardcoded secrets and public access.

## Detection

```yaml
title: Auditing Terraform Security Detection
id: f3c8a2f9-f50d-4c55-9cf1-a84f1bc58def
status: experimental
description: Detects suspicious activity related to auditing terraform security techniques in cloud security context
logsource:
  product: aws
  service: cloudtrail
detection:
  selection:
    eventName: "*Unauthorized*"
  condition: selection
level: medium
tags:
  - attack.t1195.002
  - attack.credential_access
falsepositives:
  - Automated cloud infrastructure provisioning by approved CI/CD pipelines
```

## Verification

- [ ] No hardcoded secrets in Terraform files
- [ ] All S3 buckets have encryption and public access block
- [ ] No IAM policies with `*:*` (Action:Resource wildcards)
- [ ] Security groups restrict ingress to required ports/CIDRs
- [ ] RDS/EBS/EFS encryption enabled
- [ ] CloudTrail enabled in all regions
- [ ] Terraform state stored in encrypted backend with versioning
- [ ] No infrastructure drift from Terraform state
- [ ] CI/CD pipeline includes IaC security scanning

## References

- [tfsec — Terraform Security Scanner](https://github.com/aquasecurity/tfsec)
- [Checkov — IaC Security Scanner](https://www.checkov.io/)
- [CIS Terraform AWS Benchmark](https://www.cisecurity.org/benchmark/amazon_web_services)
- [Terraform Security Best Practices](https://developer.hashicorp.com/terraform/cloud-docs/recommended-practices)
