Skip to content

ci: bump the github-actions group with 5 updates #19

ci: bump the github-actions group with 5 updates

ci: bump the github-actions group with 5 updates #19

# Security CI/CD Pipeline
# =======================
# Comprehensive security scanning for the GitHub Copilot Cybersecurity course
# Course: GitHub Copilot for Cybersecurity Specialists
#
# - Secret detection (TruffleHog, GitLeaks)
# - Dependency scanning (npm audit, Snyk)
# - SAST (CodeQL, Semgrep)
# - IaC scanning (Checkov, KICS)
# - Container scanning (Trivy)
# - Security gate enforcement
name: Security Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
# Run security scans daily at 6 AM UTC
- cron: '0 6 * * *'
workflow_dispatch:
inputs:
full_scan:
description: 'Run full security scan including DAST'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: '20'
JAVA_VERSION: '21'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# ===========================================================================
# Secret Detection - Prevent credential leaks
# ===========================================================================
secret-detection:
name: Secret Detection
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: TruffleHog Scan
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --only-verified
- name: GitLeaks Scan
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ===========================================================================
# Dependency Scanning - Identify vulnerable packages
# ===========================================================================
dependency-scan:
name: Dependency Vulnerability Scan
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: NPM Audit (Root)
run: |
if [ -f package-lock.json ]; then
npm audit --audit-level=high --json > npm-audit-root.json || true
fi
continue-on-error: true
- name: NPM Audit (NodeGoat)
working-directory: ./NodeGoat
run: |
if [ -f package-lock.json ]; then
npm audit --audit-level=critical --json > ../npm-audit-nodegoat.json || true
fi
continue-on-error: true
- name: Upload Audit Results
uses: actions/upload-artifact@v5
if: always()
with:
name: npm-audit-results
path: npm-audit-*.json
retention-days: 30
# ===========================================================================
# SAST - Semgrep Analysis
# ===========================================================================
sast-semgrep:
name: Semgrep SAST
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- name: Checkout Repository
uses: actions/checkout@v6
- name: Run Semgrep
run: |
semgrep scan \
--config p/security-audit \
--config p/owasp-top-ten \
--config p/nodejs \
--config p/javascript \
--sarif \
--output semgrep-results.sarif \
--error \
--exclude='**/node_modules/**' \
--exclude='**/vendor/**' \
--exclude='**/*.min.js' \
. || true
- name: Upload Semgrep Results
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: semgrep-results.sarif
continue-on-error: true
# ===========================================================================
# Infrastructure as Code Scanning
# ===========================================================================
iac-scan:
name: IaC Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v6
- name: Checkov Scan
uses: bridgecrewio/checkov-action@v12
with:
directory: .
framework: terraform
output_format: cli,sarif
output_file_path: console,checkov-results.sarif
soft_fail: true
skip_check: CKV_AWS_79,CKV_AWS_18
- name: Upload Checkov Results
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: checkov-results.sarif
continue-on-error: true
# ===========================================================================
# Container Security Scanning
# ===========================================================================
container-scan:
name: Container Security
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
steps:
- name: Checkout Repository
uses: actions/checkout@v6
- name: Trivy Filesystem Scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-fs-results.sarif'
severity: 'CRITICAL,HIGH'
ignore-unfixed: true
- name: Upload Trivy Results
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: trivy-fs-results.sarif
continue-on-error: true
# ===========================================================================
# Security Gate - Final approval step
# ===========================================================================
security-gate:
name: Security Gate
runs-on: ubuntu-latest
needs:
- secret-detection
- dependency-scan
- sast-semgrep
- iac-scan
if: always()
steps:
- name: Check Security Results
run: |
echo "## Security Scan Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Check each job status
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Secret Detection | ${{ needs.secret-detection.result == 'success' && 'Passed' || 'Review Required' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Dependency Scan | ${{ needs.dependency-scan.result == 'success' && 'Passed' || 'Review Required' }} |" >> $GITHUB_STEP_SUMMARY
echo "| SAST (Semgrep) | ${{ needs.sast-semgrep.result == 'success' && 'Passed' || 'Review Required' }} |" >> $GITHUB_STEP_SUMMARY
echo "| IaC Scan | ${{ needs.iac-scan.result == 'success' && 'Passed' || 'Review Required' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Note:** This repository contains intentionally vulnerable code for educational purposes." >> $GITHUB_STEP_SUMMARY
- name: Gate Decision
run: |
# Only fail on secret detection failures (critical security issue)
if [ "${{ needs.secret-detection.result }}" == "failure" ]; then
echo "::error::Security gate failed - secrets detected in code"
exit 1
fi
echo "Security gate passed"