# Checkov - Infrastructure as Code Security

Comprehensive guide to IaC security scanning with Checkov for Terraform, CloudFormation, Kubernetes, Dockerfile, and more.

## Overview

**Container**: `bridgecrew/checkov:latest`
**Category**: IaC Security Scanning
**Port**: N/A (CLI tool)

Checkov is a static code analysis tool for infrastructure-as-code that scans cloud infrastructure configurations to find misconfigurations before they're deployed.

## Quick Start

```bash
# Basic scan of current directory
docker exec checkov checkov -d /code

# Scan specific file
docker exec checkov checkov -f /code/main.tf

# Output in JSON format
docker exec checkov checkov -d /code -o json > checkov-results.json

# Compact output
docker exec checkov checkov -d /code --compact
```

## Supported Frameworks

| Framework | File Types | Example |
|-----------|------------|---------|
| Terraform | `.tf`, `.tf.json` | `main.tf` |
| CloudFormation | `.yaml`, `.yml`, `.json` | `template.yaml` |
| Kubernetes | `.yaml`, `.yml` | `deployment.yaml` |
| Dockerfile | `Dockerfile*` | `Dockerfile` |
| Helm | `Chart.yaml` + templates | Helm charts |
| ARM | `.json` | Azure Resource Manager |
| Serverless | `serverless.yml` | Serverless Framework |
| Ansible | `.yml`, `.yaml` | Ansible playbooks |
| Bicep | `.bicep` | Azure Bicep |
| Kustomize | `kustomization.yaml` | Kustomize overlays |

## CLI Commands

```bash
# Scan directory
docker exec checkov checkov -d /code

# Scan specific framework
docker exec checkov checkov -d /code --framework terraform

# Multiple frameworks
docker exec checkov checkov -d /code --framework terraform,kubernetes

# Skip specific checks
docker exec checkov checkov -d /code --skip-check CKV_AWS_1,CKV_AWS_2

# Run only specific checks
docker exec checkov checkov -d /code --check CKV_AWS_1,CKV_AWS_2

# External checks directory
docker exec checkov checkov -d /code --external-checks-dir /custom-checks

# Scan from stdin (for piping)
cat main.tf | docker exec -i checkov checkov --file -

# Soft fail (exit 0 even with failures)
docker exec checkov checkov -d /code --soft-fail
```

## Output Formats

```bash
# CLI output (default)
docker exec checkov checkov -d /code

# JSON output
docker exec checkov checkov -d /code -o json

# JUnit XML (for CI)
docker exec checkov checkov -d /code -o junitxml

# SARIF (GitHub integration)
docker exec checkov checkov -d /code -o sarif

# CSV output
docker exec checkov checkov -d /code -o csv

# Multiple outputs
docker exec checkov checkov -d /code -o cli -o json -o sarif
```

## Check Categories

| Category | Description | Example Check ID |
|----------|-------------|------------------|
| AWS | AWS resource misconfigurations | CKV_AWS_* |
| Azure | Azure resource misconfigurations | CKV_AZURE_* |
| GCP | Google Cloud misconfigurations | CKV_GCP_* |
| Kubernetes | K8s security misconfigurations | CKV_K8S_* |
| Docker | Dockerfile security issues | CKV_DOCKER_* |
| General | Cross-cloud security issues | CKV_* |

## Common Checks

### AWS Checks

| Check ID | Description |
|----------|-------------|
| CKV_AWS_1 | Ensure CloudTrail log file validation is enabled |
| CKV_AWS_2 | Ensure CloudTrail logs are encrypted at rest |
| CKV_AWS_3 | Ensure CloudTrail logging is enabled |
| CKV_AWS_5 | Ensure no IAM policy documents allow `*` action |
| CKV_AWS_7 | Ensure rotation for customer created CMKs is enabled |
| CKV_AWS_17 | Ensure RDS instance has encryption enabled |
| CKV_AWS_18 | Ensure S3 bucket has access logging enabled |
| CKV_AWS_19 | Ensure S3 bucket has encryption enabled |
| CKV_AWS_20 | Ensure S3 bucket has block public access enabled |
| CKV_AWS_21 | Ensure S3 bucket has versioning enabled |

### Kubernetes Checks

| Check ID | Description |
|----------|-------------|
| CKV_K8S_1 | Do not allow privileged containers |
| CKV_K8S_2 | Do not allow privilege escalation |
| CKV_K8S_3 | Do not allow capabilities beyond the default set |
| CKV_K8S_4 | Do not allow adding of default capabilities |
| CKV_K8S_5 | Containers should run as non-root |
| CKV_K8S_6 | Containers should use read-only filesystem |
| CKV_K8S_8 | Liveness Probe should be configured |
| CKV_K8S_9 | Readiness Probe should be configured |
| CKV_K8S_10 | CPU requests should be set |
| CKV_K8S_11 | CPU limits should be set |
| CKV_K8S_12 | Memory requests should be set |
| CKV_K8S_13 | Memory limits should be set |

### Docker Checks

| Check ID | Description |
|----------|-------------|
| CKV_DOCKER_1 | Ensure port 22 is not exposed |
| CKV_DOCKER_2 | Ensure HEALTHCHECK instructions are added |
| CKV_DOCKER_3 | Ensure USER instruction is not root |
| CKV_DOCKER_4 | Ensure COPY is used instead of ADD |
| CKV_DOCKER_5 | Ensure WORKDIR is defined |
| CKV_DOCKER_6 | Ensure SHELL is not empty |
| CKV_DOCKER_7 | Ensure base image uses a specific version tag |
| CKV_DOCKER_8 | Ensure sensitive data is not exposed |

## Configuration File

```yaml
# .checkov.yaml
branch: main
compact: true
directory:
  - /code
download-external-modules: true
evaluate-variables: true
external-checks-dir:
  - /custom-checks
framework:
  - terraform
  - kubernetes
  - dockerfile
output:
  - cli
  - json
  - sarif
quiet: false
skip-check:
  - CKV_AWS_1
  - CKV_AWS_2
soft-fail: false
```

## Custom Checks

### Python Custom Check

```python
# custom_checks/S3BucketVersioning.py
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories

class S3BucketVersioning(BaseResourceCheck):
    def __init__(self):
        name = "Ensure S3 bucket has versioning enabled"
        id = "CKV_CUSTOM_1"
        supported_resources = ['aws_s3_bucket']
        categories = [CheckCategories.BACKUP_AND_RECOVERY]
        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)

    def scan_resource_conf(self, conf):
        versioning = conf.get('versioning', [{}])
        if versioning and versioning[0].get('enabled', [False])[0]:
            return CheckResult.PASSED
        return CheckResult.FAILED

check = S3BucketVersioning()
```

### YAML Custom Check

```yaml
# custom_checks/CKV_CUSTOM_2.yaml
metadata:
  id: CKV_CUSTOM_2
  name: Ensure S3 bucket has logging enabled
  category: LOGGING
definition:
  cond_type: attribute
  resource_types:
    - aws_s3_bucket
  attribute: logging
  operator: exists
```

## Inline Suppressions

### Terraform

```hcl
# checkov:skip=CKV_AWS_1: Skip CloudTrail validation for dev environment
resource "aws_cloudtrail" "example" {
  name           = "example"
  s3_bucket_name = aws_s3_bucket.logs.id
}

# checkov:skip=CKV_AWS_2,CKV_AWS_3: Multiple skips with reason
resource "aws_s3_bucket" "example" {
  bucket = "my-bucket"
}
```

### Kubernetes

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: example
  annotations:
    checkov.io/skip1: CKV_K8S_1=Skip privileged check for system pod
    checkov.io/skip2: CKV_K8S_2=Skip privilege escalation check
spec:
  containers:
    - name: app
      image: nginx
```

### Dockerfile

```dockerfile
# checkov:skip=CKV_DOCKER_3: Running as root required for system setup
FROM ubuntu:20.04
USER root
```

## CI/CD Integration

### GitHub Actions

```yaml
name: Checkov IaC Scan
on: [push, pull_request]

jobs:
  checkov:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Run Checkov
        uses: bridgecrewio/checkov-action@master
        with:
          directory: .
          framework: terraform,kubernetes,dockerfile
          soft_fail: false
          output_format: sarif
          download_external_modules: true

      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: results.sarif
```

### GitLab CI

```yaml
checkov:
  stage: security
  image: bridgecrew/checkov:latest
  script:
    - checkov -d . --output cli --output junitxml
  artifacts:
    reports:
      junit: results_junitxml.xml
    when: always
```

## Testing Patterns

### Pre-Commit Hook

```yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/bridgecrewio/checkov.git
    rev: '2.4.0'
    hooks:
      - id: checkov
        verbose: true
        args: ['--compact']
```

### Terraform Module Testing

```bash
# Test a Terraform module
docker exec checkov checkov -d /code/modules/vpc \
  --framework terraform \
  --output json \
  --output-file-path /reports/
```

### Kubernetes Manifest Testing

```bash
# Test Kubernetes manifests
docker exec checkov checkov -d /code/k8s \
  --framework kubernetes \
  --check CKV_K8S_1,CKV_K8S_2,CKV_K8S_3,CKV_K8S_5 \
  --output junitxml
```

## Quality Gates

### Severity-Based Gating

```bash
#!/bin/bash
# quality-gate.sh

RESULTS=$(docker exec checkov checkov -d /code -o json)

CRITICAL=$(echo $RESULTS | jq '.results.failed_checks | map(select(.severity == "CRITICAL")) | length')
HIGH=$(echo $RESULTS | jq '.results.failed_checks | map(select(.severity == "HIGH")) | length')

if [ "$CRITICAL" -gt 0 ]; then
    echo "CRITICAL findings detected: $CRITICAL"
    exit 1
fi

if [ "$HIGH" -gt 5 ]; then
    echo "Too many HIGH findings: $HIGH"
    exit 1
fi

echo "Quality gate passed"
```

### Baseline Comparison

```bash
# Create baseline
docker exec checkov checkov -d /code --create-baseline

# Run against baseline
docker exec checkov checkov -d /code --baseline baseline.json
```

## Integration with Stack

- Complements Trivy for container and dependency scanning
- Results can be imported into DefectDojo for tracking
- Integrates with SonarQube for comprehensive code quality
- Works alongside Semgrep for application code security
- Output to Allure for unified reporting

## Best Practices

1. **Run early in CI/CD** - Scan before deployment to catch issues early
2. **Use baselines** - Establish acceptable state and track changes
3. **Customize checks** - Create checks for organizational policies
4. **Skip with reason** - Always document why a check is skipped
5. **Framework-specific scans** - Target frameworks for faster feedback
6. **Multiple outputs** - Generate both CLI and machine-readable formats
7. **External modules** - Enable download for accurate Terraform scanning
8. **Regular updates** - Keep Checkov updated for latest checks

## Troubleshooting

### Common Issues

**Issue**: External Terraform modules not scanned
```bash
# Enable external module download
docker exec checkov checkov -d /code --download-external-modules true
```

**Issue**: Too many false positives
```bash
# Use skip file
docker exec checkov checkov -d /code --skip-path tests/ --skip-framework secrets
```

**Issue**: Slow scans
```bash
# Use compact output and specific frameworks
docker exec checkov checkov -d /code --compact --framework terraform
```
