Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 216 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
name: Security Scanning

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
schedule:
# Run security scans daily at 2 AM UTC
- cron: '0 2 * * *'
workflow_dispatch:

permissions:
contents: read
security-events: write
actions: read

jobs:
dependency-check:
name: Dependency Vulnerability Scan
runs-on: ubuntu-latest
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: |
python -m pip install --upgrade pip
pip install safety pip-audit
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

- name: Run Safety check
run: |
safety check --json --output safety-report.json || true
safety check || true

- name: Run pip-audit
run: |
pip-audit --desc --format json --output pip-audit-report.json || true
pip-audit || true

- name: Upload dependency scan results
uses: actions/upload-artifact@v4
if: always()
with:
name: dependency-scan-results
path: |
safety-report.json
pip-audit-report.json

codeql-analysis:
name: CodeQL Security Analysis
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended,security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@v3

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

secret-scanning:
name: Secret Detection
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: TruffleHog Secret Scan
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD

container-scanning:
name: Container Security Scan
runs-on: ubuntu-latest
needs: [dependency-check]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Build Docker image
run: |
docker build -t geo-analytics-api:test .

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'geo-analytics-api:test'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH,MEDIUM'

- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'

- name: Run Trivy in table format
uses: aquasecurity/trivy-action@master
with:
image-ref: 'geo-analytics-api:test'
format: 'table'
severity: 'CRITICAL,HIGH,MEDIUM'

sast-analysis:
name: Static Application Security Testing
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install Bandit
run: |
python -m pip install --upgrade pip
pip install bandit[toml]

- name: Run Bandit security linter
run: |
bandit -r . -f json -o bandit-report.json || true
bandit -r . -f screen

- name: Upload Bandit results
uses: actions/upload-artifact@v4
if: always()
with:
name: bandit-results
path: bandit-report.json

license-check:
name: License Compliance Check
runs-on: ubuntu-latest
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: |
python -m pip install --upgrade pip
pip install pip-licenses
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

- name: Check licenses
run: |
pip-licenses --format=json --output-file=licenses.json
pip-licenses --format=markdown --output-file=licenses.md
pip-licenses

- name: Upload license reports
uses: actions/upload-artifact@v4
with:
name: license-reports
path: |
licenses.json
licenses.md

security-summary:
name: Security Scan Summary
runs-on: ubuntu-latest
needs: [dependency-check, codeql-analysis, secret-scanning, container-scanning, sast-analysis, license-check]
if: always()
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4

- name: Create security summary
run: |
echo "# Security Scan Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Scan Status" >> $GITHUB_STEP_SUMMARY
echo "- Dependency Check: ${{ needs.dependency-check.result }}" >> $GITHUB_STEP_SUMMARY
echo "- CodeQL Analysis: ${{ needs.codeql-analysis.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Secret Scanning: ${{ needs.secret-scanning.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Container Scanning: ${{ needs.container-scanning.result }}" >> $GITHUB_STEP_SUMMARY
echo "- SAST Analysis: ${{ needs.sast-analysis.result }}" >> $GITHUB_STEP_SUMMARY
echo "- License Check: ${{ needs.license-check.result }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Review the artifacts and Security tab for detailed results." >> $GITHUB_STEP_SUMMARY
Loading