Security Scanning
A single security job that runs on every pull request. Fails the PR if any tool reports critical findings.
Full Workflowโ
name: Security Scan
on:
pull_request:
branches: [main]
permissions:
contents: read
security-events: write # required to upload SARIF to GitHub Security tab
jobs:
security:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Gitleaks needs full history to scan all commits
# 1. Secret detection โ scans git history for leaked credentials
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} # required for private repos
# 2. Dependency audit โ fails on high/critical CVEs
- name: npm audit
run: npm audit --audit-level=high
# For Python projects, replace with:
# pip install pip-audit && pip-audit
# 3. Container image scan โ build image then scan it
- name: Build image for scanning
run: docker build -t scan-target:${{ github.sha }} .
- name: Trivy โ container image scan
id: trivy
uses: aquasecurity/trivy-action@v0.20.0
continue-on-error: true # run all scanners even if this one finds issues
with:
image-ref: scan-target:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: CRITICAL,HIGH
exit-code: '1'
- name: Upload Trivy SARIF to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
# 4. IaC scanning โ checks Terraform and K8s manifests
- name: Checkov โ IaC scan
id: checkov
uses: bridgecrewio/checkov-action@v12
continue-on-error: true # run even if Trivy found issues
with:
directory: .
framework: terraform,kubernetes
soft_fail: false
output_format: sarif
output_file_path: checkov-results.sarif
- name: Upload Checkov SARIF to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: checkov-results.sarif
# Fail the job if any scanner found issues (after all SARIF files are uploaded)
- name: Fail if any scanner found issues
if: steps.trivy.outcome == 'failure' || steps.checkov.outcome == 'failure'
run: exit 1
Tool Referenceโ
| Tool | What it catches | Fails on |
|---|---|---|
| Gitleaks | Secrets/credentials in git history | Any leaked secret |
| npm audit / pip-audit | Known CVEs in dependencies | High or Critical severity |
| Trivy | OS + library CVEs in container image | High or Critical severity |
| Checkov | Misconfigured IaC (Terraform, K8s) | Any failed policy check |
Tipsโ
fetch-depth: 0is required for Gitleaks โ without it, only the latest commit is checked.- SARIF results appear in repo โ Security โ Code scanning alerts after the first run.
- To allow specific Checkov checks to pass without blocking CI, add
skip_check: CKV_AWS_123to the Checkov step. - Trivy results are cached automatically โ subsequent runs on the same image are faster.