Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:51:02 +08:00
commit ff1f4bd119
252 changed files with 72682 additions and 0 deletions

View File

@@ -0,0 +1,671 @@
---
name: iac-checkov
description: >
Infrastructure as Code (IaC) security scanning using Checkov with 750+ built-in policies for Terraform,
CloudFormation, Kubernetes, Dockerfile, and ARM templates. Use when: (1) Scanning IaC files for security
misconfigurations and compliance violations, (2) Validating cloud infrastructure against CIS, PCI-DSS,
HIPAA, and SOC2 benchmarks, (3) Detecting secrets and hardcoded credentials in IaC, (4) Implementing
policy-as-code in CI/CD pipelines, (5) Generating compliance reports with remediation guidance for
cloud security posture management.
version: 0.1.0
maintainer: SirAppSec
category: devsecops
tags: [iac, checkov, terraform, kubernetes, cloudformation, compliance, policy-as-code, cloud-security]
frameworks: [PCI-DSS, HIPAA, SOC2, NIST, GDPR]
dependencies:
python: ">=3.8"
packages: [checkov]
references:
- https://www.checkov.io/
- https://github.com/bridgecrewio/checkov
- https://docs.paloaltonetworks.com/prisma/prisma-cloud
---
# Infrastructure as Code Security with Checkov
## Overview
Checkov is a static code analysis tool that scans Infrastructure as Code (IaC) files for security misconfigurations
and compliance violations before deployment. With 750+ built-in policies, Checkov helps prevent cloud security issues
by detecting problems in Terraform, CloudFormation, Kubernetes, Dockerfiles, Helm charts, and ARM templates.
Checkov performs graph-based scanning to understand resource relationships and detect complex misconfigurations that
span multiple resources, making it more powerful than simple pattern matching.
## Quick Start
### Install Checkov
```bash
# Via pip
pip install checkov
# Via Homebrew (macOS)
brew install checkov
# Via Docker
docker pull bridgecrew/checkov
```
### Scan Terraform Directory
```bash
# Scan all Terraform files in directory
checkov -d ./terraform
# Scan specific file
checkov -f ./terraform/main.tf
# Scan with specific framework
checkov -d ./infrastructure --framework terraform
```
### Scan Kubernetes Manifests
```bash
# Scan Kubernetes YAML files
checkov -d ./k8s --framework kubernetes
# Scan Helm chart
checkov -d ./helm-chart --framework helm
```
### Scan CloudFormation Template
```bash
# Scan CloudFormation template
checkov -f ./cloudformation/template.yaml --framework cloudformation
```
## Core Workflow
### Step 1: Understand Scan Scope
Identify IaC files and frameworks to scan:
```bash
# Supported frameworks
checkov --list-frameworks
# Output:
# terraform, cloudformation, kubernetes, dockerfile, helm,
# serverless, arm, secrets, ansible, github_actions, gitlab_ci
```
**Scope Considerations:**
- Scan entire infrastructure directory for comprehensive coverage
- Focus on specific frameworks during initial adoption
- Exclude generated or vendor files
- Include both production and non-production configurations
### Step 2: Run Basic Scan
Execute Checkov with appropriate output format:
```bash
# CLI output (human-readable)
checkov -d ./terraform
# JSON output (for automation)
checkov -d ./terraform -o json
# Multiple output formats
checkov -d ./terraform -o cli -o json -o sarif
# Save output to file
checkov -d ./terraform -o json --output-file-path ./reports
```
**What Checkov Detects:**
- Security misconfigurations (unencrypted resources, public access)
- Compliance violations (CIS benchmarks, industry standards)
- Secrets and hardcoded credentials
- Missing security controls (logging, monitoring, encryption)
- Insecure network configurations
- Resource relationship issues (via graph analysis)
### Step 3: Filter and Prioritize Findings
Focus on critical issues first:
```bash
# Show only high severity issues
checkov -d ./terraform --check CKV_AWS_*
# Skip specific checks (false positives)
checkov -d ./terraform --skip-check CKV_AWS_8,CKV_AWS_21
# Check against specific compliance framework
checkov -d ./terraform --compact --framework terraform \
--check CIS_AWS,CIS_AZURE
# Run only checks with specific severity
checkov -d ./terraform --check HIGH,CRITICAL
```
**Severity Levels:**
- **CRITICAL**: Immediate security risks (public S3 buckets, unencrypted databases)
- **HIGH**: Significant security concerns (missing MFA, weak encryption)
- **MEDIUM**: Important security best practices (missing tags, logging disabled)
- **LOW**: Recommendations and hardening (resource naming conventions)
### Step 4: Suppress False Positives
Use inline suppression for legitimate exceptions:
```hcl
# Terraform example
resource "aws_s3_bucket" "example" {
# checkov:skip=CKV_AWS_18:This bucket is intentionally public for static website
bucket = "my-public-website"
acl = "public-read"
}
```
```yaml
# Kubernetes example
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
annotations:
checkov.io/skip: CKV_K8S_16=Legacy application requires privileged mode
spec:
containers:
- name: app
securityContext:
privileged: true
```
See `references/suppression_guide.md` for comprehensive suppression strategies.
### Step 5: Create Custom Policies
Define organization-specific policies:
```python
# custom_checks/require_s3_versioning.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_AWS_CUSTOM_001"
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):
if 'versioning' in conf:
if conf['versioning'][0].get('enabled') == [True]:
return CheckResult.PASSED
return CheckResult.FAILED
check = S3BucketVersioning()
```
Run with custom policies:
```bash
checkov -d ./terraform --external-checks-dir ./custom_checks
```
See `references/custom_policies.md` for advanced policy development.
### Step 6: Generate Compliance Reports
Create reports for audit and compliance:
```bash
# Generate comprehensive report
checkov -d ./terraform \
-o cli -o json -o junitxml \
--output-file-path ./compliance-reports \
--repo-id my-infrastructure \
--branch main
# CycloneDX SBOM for IaC
checkov -d ./terraform -o cyclonedx
# SARIF for GitHub Security
checkov -d ./terraform -o sarif --output-file-path ./sarif-report.json
```
**Report Types:**
- **CLI**: Human-readable console output
- **JSON**: Machine-readable for automation
- **JUnit XML**: CI/CD integration (Jenkins, GitLab)
- **SARIF**: GitHub/Azure DevOps Security tab
- **CycloneDX**: Software Bill of Materials for IaC
Map findings to compliance frameworks using `references/compliance_mapping.md`.
## CI/CD Integration
### GitHub Actions
Add Checkov scanning to pull request checks:
```yaml
# .github/workflows/checkov.yml
name: Checkov IaC Security Scan
on: [push, pull_request]
jobs:
checkov-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: infrastructure/
framework: terraform
output_format: sarif
output_file_path: checkov-results.sarif
soft_fail: false
- name: Upload SARIF Report
if: always()
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: checkov-results.sarif
```
### Pre-Commit Hook
Prevent committing insecure IaC:
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/bridgecrewio/checkov
rev: 2.5.0
hooks:
- id: checkov
args: [--soft-fail]
files: \.(tf|yaml|yml|json)$
```
Install pre-commit hooks:
```bash
pip install pre-commit
pre-commit install
```
### GitLab CI
```yaml
# .gitlab-ci.yml
checkov_scan:
image: bridgecrew/checkov:latest
stage: security
script:
- checkov -d ./terraform -o json -o junitxml
--output-file-path $CI_PROJECT_DIR/checkov-report
artifacts:
reports:
junit: checkov-report/results_junitxml.xml
paths:
- checkov-report/
when: always
```
### Jenkins Pipeline
```groovy
// Jenkinsfile
pipeline {
agent any
stages {
stage('Checkov Scan') {
steps {
sh 'pip install checkov'
sh '''
checkov -d ./terraform \
-o cli -o junitxml \
--output-file-path ./reports
'''
}
}
}
post {
always {
junit 'reports/results_junitxml.xml'
}
}
}
```
See `assets/` directory for complete CI/CD templates.
## Framework-Specific Workflows
### Terraform
**Scan Terraform with Variable Files:**
```bash
# Scan with tfvars
checkov -d ./terraform --var-file ./terraform.tfvars
# Download and scan external modules
checkov -d ./terraform --download-external-modules true
# Skip Terraform plan files
checkov -d ./terraform --skip-path terraform.tfstate
```
**Common Terraform Checks:**
- CKV_AWS_19: Ensure S3 bucket has server-side encryption
- CKV_AWS_21: Ensure S3 bucket has versioning enabled
- CKV_AWS_23: Ensure Security Group ingress is not open to 0.0.0.0/0
- CKV_AWS_40: Ensure IAM policies don't use wildcard actions
- CKV_AWS_61: Ensure RDS database has encryption at rest enabled
### Kubernetes
**Scan Kubernetes Manifests:**
```bash
# Scan all YAML manifests
checkov -d ./k8s --framework kubernetes
# Scan Helm chart
checkov -d ./helm-chart --framework helm
# Scan kustomize output
kustomize build ./overlay/prod | checkov -f - --framework kubernetes
```
**Common Kubernetes Checks:**
- CKV_K8S_8: Ensure Liveness Probe is configured
- CKV_K8S_10: Ensure CPU requests are set
- CKV_K8S_11: Ensure CPU limits are set
- CKV_K8S_14: Ensure container image is not latest
- CKV_K8S_16: Ensure container is not privileged
- CKV_K8S_22: Ensure read-only root filesystem
- CKV_K8S_28: Ensure container capabilities are minimized
### CloudFormation
**Scan CloudFormation Templates:**
```bash
# Scan CloudFormation template
checkov -f ./cloudformation/stack.yaml --framework cloudformation
# Scan AWS SAM template
checkov -f ./sam-template.yaml --framework serverless
```
### Dockerfile
**Scan Dockerfiles for Security Issues:**
```bash
# Scan Dockerfile
checkov -f ./Dockerfile --framework dockerfile
# Common issues detected:
# - Running as root user
# - Using :latest tag
# - Missing HEALTHCHECK
# - Exposing sensitive ports
```
## Baseline and Drift Detection
### Create Security Baseline
Establish baseline for existing infrastructure:
```bash
# Create baseline (first scan)
checkov -d ./terraform --create-baseline
# This creates .checkov.baseline file with current findings
```
### Detect New Issues (Drift)
Compare subsequent scans against baseline:
```bash
# Compare against baseline - only fail on NEW issues
checkov -d ./terraform --baseline .checkov.baseline
# This allows existing issues while preventing new ones
```
**Use Cases:**
- Gradual remediation of legacy infrastructure
- Focus on preventing new security debt
- Phased compliance adoption
## Secret Scanning
Detect hardcoded secrets in IaC:
```bash
# Enable secrets scanning
checkov -d ./terraform --framework secrets
# Common secrets detected:
# - AWS access keys
# - API tokens
# - Private keys
# - Database passwords
# - Generic secrets (high entropy strings)
```
## Security Considerations
- **Policy Suppression Governance**: Require security team approval for suppressing CRITICAL/HIGH findings
- **CI/CD Failure Thresholds**: Configure `--hard-fail-on` for severity levels that should block deployment
- **Custom Policy Management**: Version control custom policies and review changes
- **Compliance Alignment**: Map organizational requirements to Checkov policies
- **Secrets Management**: Never commit secrets; use secret managers and rotation policies
- **Audit Logging**: Log all scan results and policy suppressions for compliance audits
- **False Positive Review**: Regularly review suppressed findings to ensure they remain valid
- **Policy Updates**: Keep Checkov updated to receive new security policies
## Bundled Resources
### Scripts (`scripts/`)
- `checkov_scan.py` - Comprehensive scanning script with multiple frameworks and output formats
- `checkov_terraform_scan.sh` - Terraform-specific scanning with variable file support
- `checkov_k8s_scan.sh` - Kubernetes manifest scanning with cluster comparison
- `checkov_baseline_create.sh` - Baseline creation and drift detection workflow
- `checkov_compliance_report.py` - Generate compliance reports (CIS, PCI-DSS, HIPAA, SOC2)
- `ci_integration.sh` - CI/CD integration examples for multiple platforms
### References (`references/`)
- `compliance_mapping.md` - Mapping of Checkov checks to CIS, PCI-DSS, HIPAA, SOC2, NIST
- `custom_policies.md` - Guide for writing custom Python and YAML policies
- `suppression_guide.md` - Best practices for suppressing false positives
- `terraform_checks.md` - Comprehensive list of Terraform checks with remediation
- `kubernetes_checks.md` - Kubernetes security checks and pod security standards
- `cloudformation_checks.md` - CloudFormation security checks with examples
### Assets (`assets/`)
- `checkov_config.yaml` - Checkov configuration file template
- `github_actions.yml` - Complete GitHub Actions workflow
- `gitlab_ci.yml` - Complete GitLab CI pipeline
- `jenkins_pipeline.groovy` - Jenkins pipeline template
- `pre_commit_config.yaml` - Pre-commit hook configuration
- `custom_policy_template.py` - Template for custom Python policies
- `policy_metadata.yaml` - Policy metadata for organization-specific policies
## Common Patterns
### Pattern 1: Progressive Compliance Adoption
Gradually increase security posture:
```bash
# Phase 1: Scan without failing (awareness)
checkov -d ./terraform --soft-fail
# Phase 2: Fail only on CRITICAL issues
checkov -d ./terraform --hard-fail-on CRITICAL
# Phase 3: Fail on CRITICAL and HIGH
checkov -d ./terraform --hard-fail-on CRITICAL,HIGH
# Phase 4: Full enforcement with baseline
checkov -d ./terraform --baseline .checkov.baseline
```
### Pattern 2: Multi-Framework Infrastructure
Scan complete infrastructure stack:
```bash
# Use bundled script for comprehensive scanning
python3 scripts/checkov_scan.py \
--infrastructure-dir ./infrastructure \
--frameworks terraform,kubernetes,dockerfile \
--output-dir ./security-reports \
--compliance CIS,PCI-DSS
```
### Pattern 3: Policy-as-Code Repository
Maintain centralized policy repository:
```
policies/
├── custom_checks/
│ ├── aws/
│ │ ├── require_encryption.py
│ │ └── require_tags.py
│ ├── kubernetes/
│ │ └── require_psp.py
├── .checkov.yaml # Global config
└── suppression_list.txt # Approved suppressions
```
### Pattern 4: Compliance-Driven Scanning
Focus on specific compliance requirements:
```bash
# CIS AWS Foundations Benchmark
checkov -d ./terraform --check CIS_AWS
# PCI-DSS compliance
checkov -d ./terraform --framework terraform \
--check CKV_AWS_19,CKV_AWS_21,CKV_AWS_61 \
-o json --output-file-path ./pci-dss-report
# HIPAA compliance
checkov -d ./terraform --framework terraform \
--compact --check CKV_AWS_17,CKV_AWS_19,CKV_AWS_61,CKV_AWS_93
```
## Integration Points
- **CI/CD**: GitHub Actions, GitLab CI, Jenkins, Azure DevOps, CircleCI, Bitbucket Pipelines
- **Version Control**: Pre-commit hooks, pull request checks, branch protection rules
- **Cloud Platforms**: AWS, Azure, GCP, OCI, Alibaba Cloud
- **IaC Tools**: Terraform, Terragrunt, CloudFormation, ARM, Pulumi
- **Container Orchestration**: Kubernetes, OpenShift, EKS, GKE, AKS
- **Policy Engines**: OPA (Open Policy Agent), Sentinel
- **Security Platforms**: Prisma Cloud, Bridgecrew Platform
- **SIEM/Logging**: Export findings to Splunk, Elasticsearch, CloudWatch
## Troubleshooting
### Issue: Too Many Findings Overwhelming Team
**Solution**: Use progressive adoption with baselines:
```bash
# Create baseline with current state
checkov -d ./terraform --create-baseline
# Only fail on new issues
checkov -d ./terraform --baseline .checkov.baseline --soft-fail-on LOW,MEDIUM
```
### Issue: False Positives for Legitimate Use Cases
**Solution**: Use inline suppressions with justification:
```hcl
# Provide clear business justification
resource "aws_security_group" "allow_office" {
# checkov:skip=CKV_AWS_23:Office IP range needs SSH access for developers
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["203.0.113.0/24"] # Office IP range
}
}
```
### Issue: Scan Takes Too Long
**Solution**: Optimize scan scope:
```bash
# Skip unnecessary paths
checkov -d ./terraform \
--skip-path .terraform/ \
--skip-path modules/vendor/ \
--skip-framework secrets
# Use compact output
checkov -d ./terraform --compact --quiet
```
### Issue: Custom Policies Not Loading
**Solution**: Verify policy structure and loading:
```bash
# Check policy syntax
python3 custom_checks/my_policy.py
# Ensure proper directory structure
checkov -d ./terraform \
--external-checks-dir ./custom_checks \
--list
# Debug with verbose output
checkov -d ./terraform --external-checks-dir ./custom_checks -v
```
### Issue: Integration with Private Terraform Modules
**Solution**: Configure module access:
```bash
# Set up Terraform credentials
export TF_TOKEN_app_terraform_io="your-token"
# Download external modules
checkov -d ./terraform --download-external-modules true
# Or scan after terraform init
cd ./terraform && terraform init
checkov -d .
```
## References
- [Checkov Documentation](https://www.checkov.io/)
- [Checkov GitHub Repository](https://github.com/bridgecrewio/checkov)
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks/)
- [Terraform Security Best Practices](https://www.terraform.io/docs/cloud/guides/recommended-practices/index.html)
- [Kubernetes Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
- [AWS Security Best Practices](https://aws.amazon.com/security/security-resources/)

View File

@@ -0,0 +1,9 @@
# Assets Directory
Place files that will be used in the output Claude produces:
- Templates
- Configuration files
- Images/logos
- Boilerplate code
These files are NOT loaded into context but copied/modified in output.

View File

@@ -0,0 +1,94 @@
# Checkov Configuration File
# Place this file as .checkov.yaml in your project root
# Framework selection
framework:
- terraform
- kubernetes
- dockerfile
- helm
# Checks to skip globally
skip-check:
# Development environment exceptions
- CKV_AWS_17 # RDS backup retention (dev envs)
- CKV_AWS_8 # CloudWatch log encryption (cost optimization)
# Low severity informational checks
- CKV_AWS_50 # Lambda tracing
- CKV_K8S_35 # Prefer secrets as files
# Paths to exclude from scanning
skip-path:
- .terraform/
- .terragrunt-cache/
- node_modules/
- vendor/
- "**/.git"
- "**/test/"
- "**/examples/"
# Severity-based configuration
soft-fail-on:
- LOW
- MEDIUM
hard-fail-on:
- CRITICAL
- HIGH
# Compact output mode
compact: true
# Quiet mode (only show failures)
quiet: false
# Download external Terraform modules
download-external-modules: true
# Output configuration
output:
- cli
- json
- sarif
# Output file path
output-file-path: ./checkov-reports
# Repository identification
repo-id: my-infrastructure
branch: main
# External checks directory
external-checks-dir:
- ./custom_checks
# Baseline file for drift detection
# baseline: .checkov.baseline
# Enable secrets scanning
# framework:
# - secrets
# Prisma Cloud/Bridgecrew integration (optional)
# bc-api-key: ${PRISMA_API_KEY}
# prisma-api-url: https://api.prismacloud.io
# Skip specific resources by regex
# skip-resources-without-violations: true
# CKV check configuration
# check:
# - CIS_AWS
# - CIS_AZURE
# - CIS_KUBERNETES
# Enable/disable specific frameworks
# skip-framework:
# - ansible
# - github_actions
# Custom policies metadata filter
# policy-metadata-filter:
# severity: HIGH,CRITICAL
# category: IAM,ENCRYPTION

View File

@@ -0,0 +1,199 @@
# GitHub Actions Workflow for Checkov IaC Security Scanning
# Place this file in .github/workflows/checkov.yml
name: Checkov IaC Security Scan
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
paths:
- '**.tf'
- '**.yaml'
- '**.yml'
- '**.json'
schedule:
# Run weekly security scans on Sunday at 2 AM
- cron: '0 2 * * 0'
workflow_dispatch:
permissions:
contents: read
security-events: write
pull-requests: write
jobs:
checkov-terraform:
name: Terraform Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Checkov on Terraform
uses: bridgecrewio/checkov-action@master
with:
directory: terraform/
framework: terraform
output_format: sarif
output_file_path: checkov-terraform.sarif
soft_fail: false
download_external_modules: true
- name: Upload SARIF Report
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: checkov-terraform.sarif
category: terraform
checkov-kubernetes:
name: Kubernetes Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Checkov on Kubernetes
uses: bridgecrewio/checkov-action@master
with:
directory: k8s/
framework: kubernetes
output_format: sarif
output_file_path: checkov-k8s.sarif
soft_fail: false
- name: Upload SARIF Report
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: checkov-k8s.sarif
category: kubernetes
checkov-dockerfile:
name: Dockerfile Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Checkov on Dockerfiles
uses: bridgecrewio/checkov-action@master
with:
directory: ./
framework: dockerfile
output_format: sarif
output_file_path: checkov-docker.sarif
soft_fail: false
- name: Upload SARIF Report
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: checkov-docker.sarif
category: dockerfile
checkov-compliance:
name: Compliance Scan (CIS, PCI-DSS)
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'schedule'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Checkov
run: pip install checkov
- name: Run CIS Compliance Scan
run: |
checkov -d terraform/ \
--framework terraform \
--check CIS_AWS,CIS_AZURE \
-o json -o cli \
--output-file-path ./compliance-reports
- name: Upload Compliance Reports
uses: actions/upload-artifact@v4
if: always()
with:
name: compliance-reports
path: compliance-reports/
retention-days: 90
security-gate:
name: Security Gate Check
runs-on: ubuntu-latest
needs: [checkov-terraform, checkov-kubernetes]
if: always()
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Dependencies
run: pip install checkov
- name: Run Checkov with Threshold
run: |
# Fail on CRITICAL and HIGH severity issues
checkov -d terraform/ \
--framework terraform \
--hard-fail-on CRITICAL,HIGH \
-o json --output-file-path ./gate-report || EXIT_CODE=$?
# Parse results
if [ -f "gate-report/results_json.json" ]; then
CRITICAL=$(jq '[.results.failed_checks[] | select(.severity == "CRITICAL")] | length' gate-report/results_json.json)
HIGH=$(jq '[.results.failed_checks[] | select(.severity == "HIGH")] | length' gate-report/results_json.json)
echo "Critical findings: $CRITICAL"
echo "High findings: $HIGH"
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "❌ Security gate failed"
exit 1
fi
fi
echo "✅ Security gate passed"
- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = JSON.parse(fs.readFileSync('gate-report/results_json.json', 'utf8'));
const summary = report.summary || {};
const passed = summary.passed || 0;
const failed = summary.failed || 0;
const skipped = summary.skipped || 0;
const body = `## Checkov IaC Security Scan Results
| Status | Count |
|--------|-------|
| ✅ Passed | ${passed} |
| ❌ Failed | ${failed} |
| ⏭️ Skipped | ${skipped} |
${failed > 0 ? '⚠️ Please review and fix the security findings before merging.' : '✅ No security issues detected!'}
`;
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});

View File

@@ -0,0 +1,218 @@
# GitLab CI/CD Pipeline for Checkov IaC Security Scanning
# Add this to your .gitlab-ci.yml file
stages:
- security
- compliance
- report
variables:
CHECKOV_IMAGE: "bridgecrew/checkov:latest"
REPORTS_DIR: "checkov-reports"
# Terraform Security Scan
checkov_terraform:
stage: security
image: $CHECKOV_IMAGE
script:
- mkdir -p $REPORTS_DIR
- |
checkov -d terraform/ \
--framework terraform \
-o json -o junitxml -o sarif \
--output-file-path $REPORTS_DIR \
--compact || EXIT_CODE=$?
- echo "Exit code: ${EXIT_CODE:-0}"
artifacts:
reports:
junit: $REPORTS_DIR/results_junitxml.xml
sast: $REPORTS_DIR/results_sarif.sarif
paths:
- $REPORTS_DIR/
when: always
expire_in: 30 days
only:
changes:
- terraform/**/*
- "*.tf"
tags:
- docker
# Kubernetes Security Scan
checkov_kubernetes:
stage: security
image: $CHECKOV_IMAGE
script:
- mkdir -p $REPORTS_DIR
- |
checkov -d k8s/ \
--framework kubernetes \
-o json -o junitxml \
--output-file-path $REPORTS_DIR \
--compact
artifacts:
reports:
junit: $REPORTS_DIR/results_junitxml.xml
paths:
- $REPORTS_DIR/
when: always
expire_in: 30 days
only:
changes:
- k8s/**/*
- "*.yaml"
- "*.yml"
tags:
- docker
# CloudFormation Security Scan
checkov_cloudformation:
stage: security
image: $CHECKOV_IMAGE
script:
- mkdir -p $REPORTS_DIR
- |
checkov -d cloudformation/ \
--framework cloudformation \
-o json -o junitxml \
--output-file-path $REPORTS_DIR \
--compact
artifacts:
reports:
junit: $REPORTS_DIR/results_junitxml.xml
paths:
- $REPORTS_DIR/
when: always
expire_in: 30 days
only:
changes:
- cloudformation/**/*
allow_failure: true
tags:
- docker
# Compliance Scan (CIS Benchmarks)
checkov_compliance:
stage: compliance
image: $CHECKOV_IMAGE
script:
- mkdir -p $REPORTS_DIR/compliance
- |
# CIS AWS Benchmark
checkov -d terraform/ \
--framework terraform \
--check CIS_AWS \
-o json -o cli \
--output-file-path $REPORTS_DIR/compliance \
--compact || true
# Parse results
if [ -f "$REPORTS_DIR/compliance/results_json.json" ]; then
FAILED=$(jq '.summary.failed' $REPORTS_DIR/compliance/results_json.json)
echo "CIS compliance failures: $FAILED"
fi
artifacts:
paths:
- $REPORTS_DIR/compliance/
when: always
expire_in: 90 days
only:
- main
- develop
tags:
- docker
# Security Gate - Fail on Critical/High
security_gate:
stage: compliance
image: $CHECKOV_IMAGE
script:
- mkdir -p $REPORTS_DIR/gate
- |
# Run scan with severity filtering
checkov -d terraform/ \
--framework terraform \
--hard-fail-on CRITICAL,HIGH \
-o json \
--output-file-path $REPORTS_DIR/gate \
--compact || EXIT_CODE=$?
# Check results
if [ -f "$REPORTS_DIR/gate/results_json.json" ]; then
CRITICAL=$(jq '[.results.failed_checks[] | select(.severity == "CRITICAL")] | length' $REPORTS_DIR/gate/results_json.json)
HIGH=$(jq '[.results.failed_checks[] | select(.severity == "HIGH")] | length' $REPORTS_DIR/gate/results_json.json)
echo "Critical findings: $CRITICAL"
echo "High findings: $HIGH"
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "❌ Security gate failed: Critical or High severity issues found"
exit 1
fi
echo "✅ Security gate passed"
fi
exit ${EXIT_CODE:-0}
artifacts:
paths:
- $REPORTS_DIR/gate/
when: always
expire_in: 30 days
dependencies:
- checkov_terraform
- checkov_kubernetes
only:
- merge_requests
- main
allow_failure: false
tags:
- docker
# Generate Summary Report
generate_report:
stage: report
image: alpine:latest
before_script:
- apk add --no-cache jq curl
script:
- |
# Generate markdown summary
cat > $REPORTS_DIR/summary.md <<EOF
# Checkov IaC Security Scan Summary
**Pipeline:** $CI_PIPELINE_ID
**Branch:** $CI_COMMIT_REF_NAME
**Commit:** $CI_COMMIT_SHORT_SHA
**Date:** $(date)
## Scan Results
EOF
# Parse Terraform scan results
if [ -f "$REPORTS_DIR/results_json.json" ]; then
echo "### Terraform Scan" >> $REPORTS_DIR/summary.md
echo "" >> $REPORTS_DIR/summary.md
echo "| Metric | Count |" >> $REPORTS_DIR/summary.md
echo "|--------|-------|" >> $REPORTS_DIR/summary.md
jq -r '.summary | "| Passed | \(.passed) |\n| Failed | \(.failed) |\n| Skipped | \(.skipped) |"' \
$REPORTS_DIR/results_json.json >> $REPORTS_DIR/summary.md
echo "" >> $REPORTS_DIR/summary.md
fi
cat $REPORTS_DIR/summary.md
artifacts:
paths:
- $REPORTS_DIR/summary.md
when: always
expire_in: 90 days
dependencies:
- checkov_terraform
- checkov_kubernetes
only:
- merge_requests
- main
- develop
tags:
- docker

View File

@@ -0,0 +1,92 @@
# Pre-commit Hook Configuration for Checkov
# Place this file as .pre-commit-config.yaml in your project root
#
# Install: pip install pre-commit
# Setup: pre-commit install
repos:
# Checkov IaC Security Scanning
- repo: https://github.com/bridgecrewio/checkov
rev: 2.5.0
hooks:
- id: checkov
name: Checkov IaC Security Scan
args:
- --soft-fail # Don't block commits (warning only)
- --compact # Concise output
- --framework=terraform # Scan Terraform files
- --framework=kubernetes # Scan Kubernetes files
- --framework=dockerfile # Scan Dockerfiles
files: \.(tf|yaml|yml|json|Dockerfile)$
exclude: |
(?x)^(
.terraform/|
.terragrunt-cache/|
vendor/|
node_modules/
)
# Strict mode (fail on Critical/High) - optional
- repo: https://github.com/bridgecrewio/checkov
rev: 2.5.0
hooks:
- id: checkov
name: Checkov Strict Mode (Critical/High)
args:
- --hard-fail-on=CRITICAL,HIGH
- --compact
- --quiet
files: \.(tf|yaml|yml)$
exclude: |
(?x)^(
.terraform/|
test/|
examples/
)
# Only run on specific branches
stages: [push]
# Terraform-specific scanning with external modules
- repo: https://github.com/bridgecrewio/checkov
rev: 2.5.0
hooks:
- id: checkov
name: Checkov Terraform (with external modules)
args:
- --download-external-modules=true
- --framework=terraform
- --soft-fail
files: \.tf$
exclude: .terraform/
# Additional code quality hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
args: [--allow-multiple-documents]
- id: check-json
- id: check-merge-conflict
- id: detect-private-key
name: Detect Private Keys (Secrets)
# Terraform formatting
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.86.0
hooks:
- id: terraform_fmt
- id: terraform_validate
- id: terraform_docs
args:
- --hook-config=--add-to-existing-file=true
- --hook-config=--create-file-if-not-exist=true
# YAML linting
- repo: https://github.com/adrienverge/yamllint
rev: v1.33.0
hooks:
- id: yamllint
args: [-c=.yamllint.yaml]
files: \.(yaml|yml)$

View File

@@ -0,0 +1,40 @@
# Reference Document Template
This file contains detailed reference material that Claude should load only when needed.
## Table of Contents
- [Section 1](#section-1)
- [Section 2](#section-2)
- [Security Standards](#security-standards)
## Section 1
Detailed information, schemas, or examples that are too large for SKILL.md.
## Section 2
Additional reference material.
## Security Standards
### OWASP Top 10
Reference relevant OWASP categories:
- A01: Broken Access Control
- A02: Cryptographic Failures
- etc.
### CWE Mappings
Map to relevant Common Weakness Enumeration categories:
- CWE-79: Cross-site Scripting
- CWE-89: SQL Injection
- etc.
### MITRE ATT&CK
Reference relevant tactics and techniques if applicable:
- TA0001: Initial Access
- T1190: Exploit Public-Facing Application
- etc.

View File

@@ -0,0 +1,237 @@
# Checkov Compliance Framework Mapping
Mapping of Checkov checks to CIS, PCI-DSS, HIPAA, SOC2, NIST, and GDPR compliance requirements.
## CIS Benchmarks
### CIS AWS Foundations Benchmark v1.4
| Check ID | CIS Control | Description | Severity |
|----------|-------------|-------------|----------|
| CKV_AWS_19 | 2.1.1 | Ensure S3 bucket encryption at rest | HIGH |
| CKV_AWS_21 | 2.1.3 | Ensure S3 bucket versioning enabled | MEDIUM |
| CKV_AWS_18 | 2.1.5 | Ensure S3 bucket access logging | MEDIUM |
| CKV_AWS_23 | 4.1 | Security group ingress not 0.0.0.0/0 | HIGH |
| CKV_AWS_24 | 4.2 | Security group ingress not ::/0 | HIGH |
| CKV_AWS_40 | 1.16 | IAM policies no wildcard actions | HIGH |
| CKV_AWS_61 | 2.3.1 | RDS encryption at rest enabled | HIGH |
| CKV_AWS_16 | 2.3.1 | RDS storage encrypted | HIGH |
| CKV_AWS_17 | 2.3.2 | RDS backup retention period | MEDIUM |
| CKV_AWS_7 | 2.9 | EBS encryption by default | HIGH |
| CKV_AWS_93 | 2.4.1 | S3 bucket public access blocked | CRITICAL |
### CIS Kubernetes Benchmark v1.6
| Check ID | CIS Control | Description | Severity |
|----------|-------------|-------------|----------|
| CKV_K8S_16 | 5.2.1 | Container not privileged | HIGH |
| CKV_K8S_22 | 5.2.6 | Read-only root filesystem | HIGH |
| CKV_K8S_28 | 5.2.7 | Minimize capabilities | HIGH |
| CKV_K8S_10 | 5.2.13 | CPU requests configured | MEDIUM |
| CKV_K8S_11 | 5.2.13 | CPU limits configured | MEDIUM |
| CKV_K8S_12 | 5.2.14 | Memory requests configured | MEDIUM |
| CKV_K8S_13 | 5.2.14 | Memory limits configured | MEDIUM |
| CKV_K8S_8 | 5.2.15 | Liveness probe configured | MEDIUM |
| CKV_K8S_9 | 5.2.15 | Readiness probe configured | MEDIUM |
## PCI-DSS v3.2.1
### Requirement 2: Do not use vendor-supplied defaults
| Check ID | PCI Requirement | Description |
|----------|-----------------|-------------|
| CKV_AWS_41 | 2.1 | EKS encryption enabled |
| CKV_AWS_58 | 2.2 | EKS public access restricted |
| CKV_K8S_14 | 2.3 | Image tag not :latest |
### Requirement 3: Protect stored cardholder data
| Check ID | PCI Requirement | Description |
|----------|-----------------|-------------|
| CKV_AWS_19 | 3.4 | S3 bucket encrypted |
| CKV_AWS_61 | 3.4 | RDS encrypted at rest |
| CKV_AWS_7 | 3.4 | EBS encryption enabled |
| CKV_AWS_89 | 3.4 | DynamoDB encryption |
### Requirement 6: Develop and maintain secure systems
| Check ID | PCI Requirement | Description |
|----------|-----------------|-------------|
| CKV_AWS_23 | 6.2 | Security groups not open |
| CKV_AWS_40 | 6.5 | IAM no wildcard permissions |
| CKV_K8S_16 | 6.5 | No privileged containers |
### Requirement 10: Track and monitor all access
| Check ID | PCI Requirement | Description |
|----------|-----------------|-------------|
| CKV_AWS_18 | 10.2 | S3 access logging enabled |
| CKV_AWS_51 | 10.3 | ECR image scanning |
| CKV_AWS_46 | 10.5 | ECS task logging |
## HIPAA Security Rule
### Administrative Safeguards (§164.308)
| Check ID | HIPAA Control | Description |
|----------|---------------|-------------|
| CKV_AWS_40 | §164.308(a)(3) | IAM access controls |
| CKV_AWS_49 | §164.308(a)(4) | CloudTrail logging |
| CKV_AWS_38 | §164.308(a)(5) | EKS RBAC enabled |
### Physical Safeguards (§164.310)
| Check ID | HIPAA Control | Description |
|----------|---------------|-------------|
| CKV_AWS_19 | §164.310(d)(1) | Encryption at rest (S3) |
| CKV_AWS_7 | §164.310(d)(1) | Encryption at rest (EBS) |
| CKV_AWS_61 | §164.310(d)(1) | Encryption at rest (RDS) |
### Technical Safeguards (§164.312)
| Check ID | HIPAA Control | Description |
|----------|---------------|-------------|
| CKV_AWS_23 | §164.312(a)(1) | Access control (network) |
| CKV_AWS_18 | §164.312(b) | Audit logging (S3) |
| CKV_AWS_27 | §164.312(c)(1) | SQS encryption |
| CKV_AWS_20 | §164.312(e)(1) | S3 SSL/TLS enforced |
## SOC 2 Trust Service Criteria
### CC6.1: Logical and Physical Access Controls
| Check ID | TSC | Description |
|----------|-----|-------------|
| CKV_AWS_40 | CC6.1 | IAM least privilege |
| CKV_AWS_23 | CC6.1 | Network segmentation |
| CKV_K8S_21 | CC6.1 | Namespace defined |
### CC6.6: Encryption
| Check ID | TSC | Description |
|----------|-----|-------------|
| CKV_AWS_19 | CC6.6 | S3 encryption |
| CKV_AWS_7 | CC6.6 | EBS encryption |
| CKV_AWS_61 | CC6.6 | RDS encryption |
| CKV_AWS_20 | CC6.6 | S3 SSL enforced |
### CC7.2: System Monitoring
| Check ID | TSC | Description |
|----------|-----|-------------|
| CKV_AWS_18 | CC7.2 | S3 access logging |
| CKV_AWS_49 | CC7.2 | CloudTrail enabled |
| CKV_K8S_8 | CC7.2 | Liveness probe |
## NIST 800-53 Rev 5
### AC (Access Control)
| Check ID | NIST Control | Description |
|----------|--------------|-------------|
| CKV_AWS_40 | AC-3 | IAM least privilege |
| CKV_AWS_23 | AC-4 | Network access control |
| CKV_K8S_16 | AC-6 | Least privilege (containers) |
### AU (Audit and Accountability)
| Check ID | NIST Control | Description |
|----------|--------------|-------------|
| CKV_AWS_18 | AU-2 | S3 access logging |
| CKV_AWS_49 | AU-12 | CloudTrail logging |
| CKV_K8S_35 | AU-9 | Audit log protection |
### SC (System and Communications Protection)
| Check ID | NIST Control | Description |
|----------|--------------|-------------|
| CKV_AWS_19 | SC-28 | Encryption at rest (S3) |
| CKV_AWS_20 | SC-8 | Encryption in transit (S3) |
| CKV_AWS_7 | SC-28 | Encryption at rest (EBS) |
## GDPR
### Article 32: Security of Processing
| Check ID | GDPR Article | Description |
|----------|--------------|-------------|
| CKV_AWS_19 | Art. 32(1)(a) | Encryption of personal data |
| CKV_AWS_7 | Art. 32(1)(a) | EBS encryption |
| CKV_AWS_61 | Art. 32(1)(a) | RDS encryption |
| CKV_AWS_21 | Art. 32(1)(b) | Data backup (S3 versioning) |
| CKV_AWS_18 | Art. 32(1)(d) | Access logging |
### Article 25: Data Protection by Design
| Check ID | GDPR Article | Description |
|----------|--------------|-------------|
| CKV_AWS_93 | Art. 25 | S3 public access block |
| CKV_AWS_23 | Art. 25 | Network isolation |
| CKV_AWS_20 | Art. 25 | Secure transmission |
## Usage Examples
### Scan for CIS Compliance
```bash
# CIS AWS Benchmark
checkov -d ./terraform --check CIS_AWS
# CIS Azure Benchmark
checkov -d ./terraform --check CIS_AZURE
# CIS Kubernetes Benchmark
checkov -d ./k8s --framework kubernetes --check CIS_KUBERNETES
```
### Scan for PCI-DSS Compliance
```bash
# Focus on encryption requirements (Req 3.4)
checkov -d ./terraform \
--check CKV_AWS_19,CKV_AWS_61,CKV_AWS_7,CKV_AWS_89
# Network security (Req 1, 2)
checkov -d ./terraform \
--check CKV_AWS_23,CKV_AWS_24,CKV_AWS_40
```
### Scan for HIPAA Compliance
```bash
# HIPAA-focused scan
checkov -d ./terraform \
--check CKV_AWS_19,CKV_AWS_7,CKV_AWS_61,CKV_AWS_20,CKV_AWS_18,CKV_AWS_40
```
### Generate Compliance Report
```bash
# Comprehensive compliance report
checkov -d ./terraform \
-o json --output-file-path ./compliance-report \
--repo-id healthcare-infra \
--check CIS_AWS,PCI_DSS,HIPAA
```
## Compliance Matrix
| Framework | Checkov Support | Common Checks | Report Format |
|-----------|-----------------|---------------|---------------|
| CIS AWS | ✓ Full | 100+ checks | JSON, CLI, SARIF |
| CIS Azure | ✓ Full | 80+ checks | JSON, CLI, SARIF |
| CIS Kubernetes | ✓ Full | 50+ checks | JSON, CLI, SARIF |
| PCI-DSS 3.2.1 | ✓ Partial | 30+ checks | JSON, CLI |
| HIPAA | ✓ Partial | 40+ checks | JSON, CLI |
| SOC 2 | ✓ Partial | 35+ checks | JSON, CLI |
| NIST 800-53 | ✓ Mapping | 60+ checks | JSON, CLI |
| GDPR | ✓ Mapping | 25+ checks | JSON, CLI |
## Additional Resources
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks/)
- [PCI Security Standards](https://www.pcisecuritystandards.org/)
- [HIPAA Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html)
- [AICPA SOC 2](https://www.aicpa.org/soc4so)
- [NIST 800-53](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final)
- [GDPR Portal](https://gdpr.eu/)

View File

@@ -0,0 +1,460 @@
# Checkov Custom Policy Development Guide
Complete guide for creating organization-specific security policies in Python and YAML.
## Overview
Custom policies allow you to enforce organization-specific security requirements beyond Checkov's built-in checks. Policies can be written in:
- **Python**: Full programmatic control, graph-based analysis
- **YAML**: Simple attribute checks, easy to maintain
## Python-Based Custom Policies
### Basic Resource Check
```python
# custom_checks/require_resource_tags.py
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories
class RequireResourceTags(BaseResourceCheck):
def __init__(self):
name = "Ensure all resources have required tags"
id = "CKV_AWS_CUSTOM_001"
supported_resources = ['aws_*'] # All AWS resources
categories = [CheckCategories.CONVENTION]
super().__init__(name=name, id=id, categories=categories,
supported_resources=supported_resources)
def scan_resource_conf(self, conf):
"""Check if resource has required tags."""
required_tags = ['Environment', 'Owner', 'CostCenter']
tags = conf.get('tags')
if not tags or not isinstance(tags, list):
return CheckResult.FAILED
tag_dict = tags[0] if tags else {}
for required_tag in required_tags:
if required_tag not in tag_dict:
self.evaluated_keys = ['tags']
return CheckResult.FAILED
return CheckResult.PASSED
check = RequireResourceTags()
```
### Graph-Based Policy
```python
# custom_checks/s3_bucket_policy_public.py
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories
class S3BucketPolicyNotPublic(BaseResourceCheck):
def __init__(self):
name = "Ensure S3 bucket policy doesn't allow public access"
id = "CKV_AWS_CUSTOM_002"
supported_resources = ['aws_s3_bucket_policy']
categories = [CheckCategories.IAM]
super().__init__(name=name, id=id, categories=categories,
supported_resources=supported_resources)
def scan_resource_conf(self, conf):
"""Scan S3 bucket policy for public access."""
policy = conf.get('policy')
if not policy:
return CheckResult.PASSED
import json
try:
policy_doc = json.loads(policy[0]) if isinstance(policy, list) else json.loads(policy)
except (json.JSONDecodeError, TypeError):
return CheckResult.UNKNOWN
statements = policy_doc.get('Statement', [])
for statement in statements:
effect = statement.get('Effect')
principal = statement.get('Principal', {})
# Check for public access
if effect == 'Allow':
if principal == '*' or principal.get('AWS') == '*':
return CheckResult.FAILED
return CheckResult.PASSED
check = S3BucketPolicyNotPublic()
```
### Connection-Aware Check (Graph)
```python
# custom_checks/ec2_in_private_subnet.py
from checkov.terraform.checks.resource.base_resource_value_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories
class EC2InPrivateSubnet(BaseResourceCheck):
def __init__(self):
name = "Ensure EC2 instances are in private subnets"
id = "CKV_AWS_CUSTOM_003"
supported_resources = ['aws_instance']
categories = [CheckCategories.NETWORKING]
super().__init__(name=name, id=id, categories=categories,
supported_resources=supported_resources)
def scan_resource_conf(self, conf, entity_type):
"""Check if EC2 instance is in private subnet."""
subnet_id = conf.get('subnet_id')
if not subnet_id:
return CheckResult.PASSED
# Use graph to find connected subnet
# This requires access to the graph context
# Implementation depends on Checkov version
return CheckResult.UNKNOWN # Implement graph logic
check = EC2InPrivateSubnet()
```
## YAML-Based Custom Policies
### Simple Attribute Check
```yaml
# custom_checks/s3_lifecycle.yaml
metadata:
id: "CKV_AWS_CUSTOM_004"
name: "Ensure S3 buckets have lifecycle policies"
category: "BACKUP_AND_RECOVERY"
severity: "MEDIUM"
definition:
cond_type: "attribute"
resource_types:
- "aws_s3_bucket"
attribute: "lifecycle_rule"
operator: "exists"
```
### Complex Logic
```yaml
# custom_checks/rds_multi_az.yaml
metadata:
id: "CKV_AWS_CUSTOM_005"
name: "Ensure RDS instances are multi-AZ for production"
category: "BACKUP_AND_RECOVERY"
severity: "HIGH"
definition:
or:
- cond_type: "attribute"
resource_types:
- "aws_db_instance"
attribute: "multi_az"
operator: "equals"
value: true
- and:
- cond_type: "attribute"
resource_types:
- "aws_db_instance"
attribute: "tags.Environment"
operator: "not_equals"
value: "production"
```
### Kubernetes Policy
```yaml
# custom_checks/k8s_service_account.yaml
metadata:
id: "CKV_K8S_CUSTOM_001"
name: "Ensure pods use dedicated service accounts"
category: "IAM"
severity: "HIGH"
definition:
cond_type: "attribute"
resource_types:
- "Pod"
- "Deployment"
- "StatefulSet"
- "DaemonSet"
attribute: "spec.serviceAccountName"
operator: "not_equals"
value: "default"
```
## Policy Structure
### Python Policy Template
```python
#!/usr/bin/env python3
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories
class MyCustomCheck(BaseResourceCheck):
def __init__(self):
# Metadata
name = "Check description"
id = "CKV_[PROVIDER]_CUSTOM_[NUMBER]" # e.g., CKV_AWS_CUSTOM_001
supported_resources = ['resource_type'] # e.g., ['aws_s3_bucket']
categories = [CheckCategories.CATEGORY] # See categories below
guideline = "https://docs.example.com/security-policy"
super().__init__(
name=name,
id=id,
categories=categories,
supported_resources=supported_resources,
guideline=guideline
)
def scan_resource_conf(self, conf, entity_type=None):
"""
Scan resource configuration for compliance.
Args:
conf: Resource configuration dictionary
entity_type: Resource type (optional)
Returns:
CheckResult.PASSED, CheckResult.FAILED, or CheckResult.UNKNOWN
"""
# Implementation
if self.check_condition(conf):
return CheckResult.PASSED
self.evaluated_keys = ['attribute_that_failed']
return CheckResult.FAILED
def get_inspected_key(self):
"""Return the key that was checked."""
return 'attribute_name'
check = MyCustomCheck()
```
### Check Categories
```python
from checkov.common.models.enums import CheckCategories
# Available categories:
CheckCategories.IAM
CheckCategories.NETWORKING
CheckCategories.ENCRYPTION
CheckCategories.LOGGING
CheckCategories.BACKUP_AND_RECOVERY
CheckCategories.CONVENTION
CheckCategories.SECRETS
CheckCategories.KUBERNETES
CheckCategories.API_SECURITY
CheckCategories.SUPPLY_CHAIN
```
## Loading Custom Policies
### Directory Structure
```
custom_checks/
├── aws/
│ ├── require_tags.py
│ ├── s3_lifecycle.yaml
│ └── rds_backups.py
├── kubernetes/
│ ├── require_resource_limits.py
│ └── security_context.yaml
└── azure/
└── storage_encryption.py
```
### Load Policies
```bash
# Load from directory
checkov -d ./terraform --external-checks-dir ./custom_checks
# Load specific policy
checkov -d ./terraform --external-checks-git https://github.com/org/policies.git
# List loaded custom checks
checkov -d ./terraform --external-checks-dir ./custom_checks --list
```
## Testing Custom Policies
### Unit Testing
```python
# tests/test_require_tags.py
import unittest
from custom_checks.require_resource_tags import RequireResourceTags
from checkov.common.models.enums import CheckResult
class TestRequireResourceTags(unittest.TestCase):
def setUp(self):
self.check = RequireResourceTags()
def test_pass_with_all_tags(self):
resource_conf = {
'tags': [{
'Environment': 'production',
'Owner': 'team@example.com',
'CostCenter': 'engineering'
}]
}
result = self.check.scan_resource_conf(resource_conf)
self.assertEqual(result, CheckResult.PASSED)
def test_fail_missing_tag(self):
resource_conf = {
'tags': [{
'Environment': 'production',
'Owner': 'team@example.com'
# Missing CostCenter
}]
}
result = self.check.scan_resource_conf(resource_conf)
self.assertEqual(result, CheckResult.FAILED)
def test_fail_no_tags(self):
resource_conf = {}
result = self.check.scan_resource_conf(resource_conf)
self.assertEqual(result, CheckResult.FAILED)
if __name__ == '__main__':
unittest.main()
```
### Integration Testing
```bash
# Test against sample infrastructure
checkov -d ./tests/fixtures/terraform \
--external-checks-dir ./custom_checks \
--check CKV_AWS_CUSTOM_001
# Verify output format
checkov -d ./tests/fixtures/terraform \
--external-checks-dir ./custom_checks \
-o json | jq '.results.failed_checks[] | select(.check_id == "CKV_AWS_CUSTOM_001")'
```
## Common Patterns
### Pattern 1: Naming Convention Check
```python
import re
class ResourceNamingConvention(BaseResourceCheck):
def scan_resource_conf(self, conf):
"""Enforce naming convention: env-app-resource"""
pattern = r'^(dev|staging|prod)-[a-z]+-[a-z0-9-]+$'
name = conf.get('name')
if not name or not isinstance(name, list):
return CheckResult.FAILED
resource_name = name[0] if isinstance(name[0], str) else str(name[0])
if not re.match(pattern, resource_name):
self.evaluated_keys = ['name']
return CheckResult.FAILED
return CheckResult.PASSED
```
### Pattern 2: Environment-Specific Requirements
```python
class ProductionEncryption(BaseResourceCheck):
def scan_resource_conf(self, conf):
"""Require encryption for production resources."""
tags = conf.get('tags', [{}])[0]
environment = tags.get('Environment', '')
# Only enforce for production
if environment.lower() != 'production':
return CheckResult.PASSED
# Check encryption
encryption_enabled = conf.get('server_side_encryption_configuration')
if not encryption_enabled:
return CheckResult.FAILED
return CheckResult.PASSED
```
### Pattern 3: Cost Optimization
```python
class EC2InstanceSizing(BaseResourceCheck):
def scan_resource_conf(self, conf):
"""Prevent oversized instances in non-production."""
tags = conf.get('tags', [{}])[0]
environment = tags.get('Environment', '')
# Only restrict non-production
if environment.lower() == 'production':
return CheckResult.PASSED
instance_type = conf.get('instance_type', [''])[0]
oversized_types = ['c5.9xlarge', 'c5.12xlarge', 'c5.18xlarge']
if instance_type in oversized_types:
self.evaluated_keys = ['instance_type']
return CheckResult.FAILED
return CheckResult.PASSED
```
## Best Practices
1. **ID Convention**: Use `CKV_[PROVIDER]_CUSTOM_[NUMBER]` format
2. **Documentation**: Include guideline URL in check metadata
3. **Error Handling**: Return `CheckResult.UNKNOWN` for ambiguous cases
4. **Performance**: Minimize complex operations in scan loops
5. **Testing**: Write unit tests for all custom policies
6. **Versioning**: Track policy versions in version control
7. **Review Process**: Require security team review before deployment
## Troubleshooting
### Policy Not Loading
```bash
# Debug loading
checkov -d ./terraform --external-checks-dir ./custom_checks -v
# Verify syntax
python3 custom_checks/my_policy.py
# Check for import errors
python3 -c "import custom_checks.my_policy"
```
### Policy Not Triggering
```bash
# Verify resource type matches
checkov -d ./terraform --external-checks-dir ./custom_checks --list
# Test with specific check
checkov -d ./terraform --check CKV_AWS_CUSTOM_001 -v
```
## Additional Resources
- [Checkov Custom Policies Documentation](https://www.checkov.io/3.Custom%20Policies/Custom%20Policies%20Overview.html)
- [Python Policy Examples](https://github.com/bridgecrewio/checkov/tree/master/checkov/terraform/checks)
- [YAML Policy Examples](https://github.com/bridgecrewio/checkov/tree/master/checkov/terraform/checks/graph_checks)

View File

@@ -0,0 +1,431 @@
# Checkov Suppression and Exception Handling Guide
Best practices for suppressing false positives and managing policy exceptions in Checkov.
## Suppression Methods
### Inline Suppression (Recommended)
#### Terraform
```hcl
# Single check suppression with justification
resource "aws_s3_bucket" "public_site" {
# checkov:skip=CKV_AWS_18:Public bucket for static website hosting
bucket = "my-public-website"
acl = "public-read"
}
# Multiple checks suppression
resource "aws_security_group" "legacy" {
# checkov:skip=CKV_AWS_23:Legacy app requires open access
# checkov:skip=CKV_AWS_24:IPv6 not supported by application
name = "legacy-sg"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
```
#### Kubernetes
```yaml
# Annotation-based suppression
apiVersion: v1
kind: Pod
metadata:
name: legacy-app
annotations:
checkov.io/skip: CKV_K8S_16=Legacy application requires elevated privileges
spec:
containers:
- name: app
image: myapp:1.0
securityContext:
privileged: true
```
#### CloudFormation
```yaml
Resources:
PublicBucket:
Type: AWS::S3::Bucket
Metadata:
checkov:
skip:
- id: CKV_AWS_18
comment: "Public bucket for CDN origin"
Properties:
BucketName: my-public-bucket
PublicAccessBlockConfiguration:
BlockPublicAcls: false
```
### Configuration File Suppression
#### .checkov.yaml
```yaml
# .checkov.yaml (project root)
skip-check:
- CKV_AWS_8 # Ensure CloudWatch log groups encrypted
- CKV_K8S_43 # Image pull policy Always
# Skip specific paths
skip-path:
- .terraform/
- node_modules/
- vendor/
# Severity-based soft fail
soft-fail-on:
- LOW
- MEDIUM
# Hard fail on critical/high only
hard-fail-on:
- CRITICAL
- HIGH
```
### CLI-Based Suppression
```bash
# Skip specific checks
checkov -d ./terraform --skip-check CKV_AWS_8,CKV_AWS_21
# Skip entire frameworks
checkov -d ./infra --skip-framework secrets
# Skip paths
checkov -d ./terraform --skip-path .terraform/ --skip-path vendor/
```
## Suppression Governance
### Approval Workflow
```yaml
# .github/workflows/checkov-review.yml
name: Review Checkov Suppressions
on:
pull_request:
paths:
- '**.tf'
- '**.yaml'
- '**.yml'
jobs:
check-suppressions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check for New Suppressions
run: |
# Count suppressions in PR
SUPPRESSIONS=$(git diff origin/main | grep -c "checkov:skip" || true)
if [ "$SUPPRESSIONS" -gt 0 ]; then
echo "::warning::PR contains $SUPPRESSIONS new suppression(s)"
echo "Security team review required"
# Request review from security team
fi
```
### Suppression Documentation Template
```hcl
resource "aws_security_group" "example" {
# checkov:skip=CKV_AWS_23:TICKET-1234 - Business justification here
# Approved by: security-team@example.com
# Review date: 2024-01-15
# Expiration: 2024-06-15 (review quarterly)
#
# Compensating controls:
# - WAF rule blocks malicious traffic
# - Application-level authentication required
# - IP allow-listing at load balancer
# - 24/7 monitoring and alerting
name = "approved-exception"
# ... configuration
}
```
## Suppression Best Practices
### 1. Always Provide Justification
```hcl
# ❌ BAD: No justification
resource "aws_s3_bucket" "example" {
# checkov:skip=CKV_AWS_18
bucket = "my-bucket"
}
# ✅ GOOD: Clear business justification
resource "aws_s3_bucket" "example" {
# checkov:skip=CKV_AWS_18:Public bucket required for static website hosting.
# Content is non-sensitive marketing materials. CloudFront restricts direct access.
bucket = "marketing-website"
}
```
### 2. Document Compensating Controls
```hcl
resource "aws_security_group" "app" {
# checkov:skip=CKV_AWS_23:Office IP range access required for developers
#
# Compensating controls:
# 1. IP range limited to corporate /24 subnet (203.0.113.0/24)
# 2. MFA required for VPN access to corporate network
# 3. Additional application-level authentication
# 4. Session timeout of 15 minutes
# 5. All access logged to SIEM
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["203.0.113.0/24"]
}
}
```
### 3. Set Expiration Dates
```hcl
resource "aws_instance" "temp" {
# checkov:skip=CKV_AWS_8:Temporary instance for POC
# EXPIRES: 2024-03-31
# After expiration: Remove or apply encryption
ami = "ami-12345678"
instance_type = "t3.micro"
}
```
### 4. Use Granular Suppressions
```hcl
# ❌ BAD: Suppress entire file or directory
# checkov:skip=* (Don't do this!)
# ✅ GOOD: Suppress specific checks on specific resources
resource "aws_s3_bucket" "example" {
# checkov:skip=CKV_AWS_18:Specific reason for this resource only
bucket = "specific-bucket"
}
```
## Exception Categories
### Legitimate Exceptions
#### 1. Public Resources by Design
```hcl
resource "aws_s3_bucket" "website" {
# checkov:skip=CKV_AWS_18:Public bucket for static website
# checkov:skip=CKV_AWS_93:Public access required by design
# Content: Marketing materials (non-sensitive)
# Access: Read-only via CloudFront
bucket = "company-website"
}
```
#### 2. Legacy System Constraints
```yaml
apiVersion: v1
kind: Pod
metadata:
name: legacy-app
annotations:
checkov.io/skip: CKV_K8S_16=Legacy app built before containers, requires host access
# Migration plan: TICKET-5678
# Target date: Q2 2024
spec:
hostNetwork: true
containers:
- name: legacy
image: legacy-app:1.0
```
#### 3. Development/Testing Environments
```hcl
resource "aws_db_instance" "dev_db" {
# checkov:skip=CKV_AWS_17:Dev environment - backups not required
# checkov:skip=CKV_AWS_61:Dev environment - encryption overhead not needed
# Environment: Non-production only
# Data: Synthetic test data (no PII/PHI)
identifier = "dev-database"
backup_retention_period = 0
storage_encrypted = false
tags = {
Environment = "development"
}
}
```
### Temporary Exceptions
```hcl
resource "aws_rds_cluster" "temp_unencrypted" {
# checkov:skip=CKV_AWS_96:Temporary exception during migration
# TICKET: INFRA-1234
# EXPIRES: 2024-02-15
# PLAN: Enable encryption at rest in Phase 2 migration
# OWNER: platform-team@example.com
cluster_identifier = "migration-temp"
storage_encrypted = false
}
```
## Suppression Anti-Patterns
### ❌ Don't: Blanket Suppressions
```yaml
# BAD: Suppress all checks
skip-check:
- "*"
```
### ❌ Don't: Suppress Without Documentation
```hcl
# BAD: No explanation
resource "aws_s3_bucket" "example" {
# checkov:skip=CKV_AWS_18
bucket = "my-bucket"
}
```
### ❌ Don't: Permanent Suppressions for Production
```hcl
# BAD: Permanent suppression of critical security control
resource "aws_rds_cluster" "prod" {
# checkov:skip=CKV_AWS_96:Too expensive
# ^ This is unacceptable for production!
cluster_identifier = "production-db"
storage_encrypted = false
}
```
### ❌ Don't: Suppress High/Critical Without Review
```hcl
# DANGEROUS: Suppressing critical finding without security review
resource "aws_security_group" "prod" {
# checkov:skip=CKV_AWS_23:Need access from anywhere
# ^ Requires security team approval!
ingress {
cidr_blocks = ["0.0.0.0/0"]
}
}
```
## Monitoring Suppressions
### Track Suppression Metrics
```bash
# Count suppressions by type
grep -r "checkov:skip" ./terraform | \
sed 's/.*checkov:skip=\([^:]*\).*/\1/' | \
sort | uniq -c | sort -rn
# Find suppressions without justification
grep -r "checkov:skip=" ./terraform | \
grep -v "checkov:skip=.*:.*"
```
### Suppression Audit Report
```python
#!/usr/bin/env python3
"""Generate suppression audit report."""
import re
import sys
from pathlib import Path
from datetime import datetime
def find_suppressions(directory):
"""Find all Checkov suppressions."""
suppressions = []
for file_path in Path(directory).rglob('*.tf'):
with open(file_path) as f:
content = f.read()
# Find suppressions
matches = re.findall(
r'#\s*checkov:skip=([^:]+):(.*)',
content
)
for check_id, reason in matches:
suppressions.append({
'file': str(file_path),
'check_id': check_id.strip(),
'reason': reason.strip()
})
return suppressions
def generate_report(suppressions):
"""Generate markdown report."""
print("# Checkov Suppression Audit Report")
print(f"\nGenerated: {datetime.now().isoformat()}")
print(f"\nTotal Suppressions: {len(suppressions)}\n")
print("## Suppressions by Check")
check_counts = {}
for s in suppressions:
check_counts[s['check_id']] = check_counts.get(s['check_id'], 0) + 1
for check_id, count in sorted(check_counts.items(), key=lambda x: -x[1]):
print(f"- {check_id}: {count}")
print("\n## All Suppressions")
for s in suppressions:
print(f"\n### {s['file']}")
print(f"**Check:** {s['check_id']}")
print(f"**Reason:** {s['reason'] or '(no justification provided)'}")
if __name__ == '__main__':
directory = sys.argv[1] if len(sys.argv) > 1 else './terraform'
suppressions = find_suppressions(directory)
generate_report(suppressions)
```
## Quarterly Review Process
1. **Generate Suppression Report**: List all active suppressions
2. **Review Expirations**: Check for expired temporary suppressions
3. **Validate Justifications**: Ensure reasons still apply
4. **Verify Compensating Controls**: Confirm controls are still in place
5. **Update or Remove**: Update suppressions or fix underlying issues
## Additional Resources
- [Checkov Suppression Documentation](https://www.checkov.io/2.Basics/Suppressing%20and%20Skipping%20Policies.html)
- [Security Exception Management Best Practices](https://owasp.org/www-community/Security_Exception_Management)