200 lines
5.6 KiB
YAML
200 lines
5.6 KiB
YAML
# 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
|
|
});
|