Initial commit
This commit is contained in:
671
skills/devsecops/iac-checkov/SKILL.md
Normal file
671
skills/devsecops/iac-checkov/SKILL.md
Normal 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/)
|
||||
9
skills/devsecops/iac-checkov/assets/.gitkeep
Normal file
9
skills/devsecops/iac-checkov/assets/.gitkeep
Normal 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.
|
||||
94
skills/devsecops/iac-checkov/assets/checkov_config.yaml
Normal file
94
skills/devsecops/iac-checkov/assets/checkov_config.yaml
Normal 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
|
||||
199
skills/devsecops/iac-checkov/assets/github_actions.yml
Normal file
199
skills/devsecops/iac-checkov/assets/github_actions.yml
Normal 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
|
||||
});
|
||||
218
skills/devsecops/iac-checkov/assets/gitlab_ci.yml
Normal file
218
skills/devsecops/iac-checkov/assets/gitlab_ci.yml
Normal 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
|
||||
92
skills/devsecops/iac-checkov/assets/pre_commit_config.yaml
Normal file
92
skills/devsecops/iac-checkov/assets/pre_commit_config.yaml
Normal 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)$
|
||||
40
skills/devsecops/iac-checkov/references/EXAMPLE.md
Normal file
40
skills/devsecops/iac-checkov/references/EXAMPLE.md
Normal 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.
|
||||
237
skills/devsecops/iac-checkov/references/compliance_mapping.md
Normal file
237
skills/devsecops/iac-checkov/references/compliance_mapping.md
Normal 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/)
|
||||
460
skills/devsecops/iac-checkov/references/custom_policies.md
Normal file
460
skills/devsecops/iac-checkov/references/custom_policies.md
Normal 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)
|
||||
431
skills/devsecops/iac-checkov/references/suppression_guide.md
Normal file
431
skills/devsecops/iac-checkov/references/suppression_guide.md
Normal 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)
|
||||
Reference in New Issue
Block a user