Skip to main content

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โ€‹

ToolWhat it catchesFails on
GitleaksSecrets/credentials in git historyAny leaked secret
npm audit / pip-auditKnown CVEs in dependenciesHigh or Critical severity
TrivyOS + library CVEs in container imageHigh or Critical severity
CheckovMisconfigured IaC (Terraform, K8s)Any failed policy check

Tipsโ€‹

  • fetch-depth: 0 is 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_123 to the Checkov step.
  • Trivy results are cached automatically โ€” subsequent runs on the same image are faster.