From 25f223020cabc53b42c179a54ae8ce02beae3e4e Mon Sep 17 00:00:00 2001 From: Adonis Jimenez Date: Sat, 17 Jan 2026 07:12:56 -0500 Subject: [PATCH] Add security scanning workflow with multiple checks This workflow sets up various security scans including dependency checks, CodeQL analysis, secret detection, container scanning, SAST analysis, and license compliance checks. It also summarizes the results of these scans. --- .github/workflows/security.yml | 216 +++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 .github/workflows/security.yml diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..74a3604 --- /dev/null +++ b/.github/workflows/security.yml @@ -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