Skip to content

Remediate codebase health issues #415

Remediate codebase health issues

Remediate codebase health issues #415

Workflow file for this run

name: Security Scanning
on:
push:
branches: [main, develop]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
- '*.md'
- 'plan/**'
- 'LICENSE'
- '.github/workflows/deploy-docs.yml'
pull_request:
branches: [main, develop]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
- '*.md'
- 'plan/**'
- 'LICENSE'
- '.github/workflows/deploy-docs.yml'
schedule:
# Weekly Monday 6 AM UTC - regular security audits
- cron: '0 6 * * 1'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# Python dependency vulnerability scanning
pip-audit:
name: Python Dependency Scan (pip-audit)
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
security-events: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Cache uv dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/uv
.venv
key: ${{ runner.os }}-uv-security-${{ hashFiles('uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-security-
${{ runner.os }}-uv-
- name: Install dependencies
run: uv sync --all-extras --dev
- name: Export locked Python dependencies
run: |
uv export --format requirements-txt --all-extras --dev --no-emit-project --no-hashes > audit-requirements.txt
- name: Run pip-audit
run: |
uv run pip-audit --requirement audit-requirements.txt --vulnerability-service pypi
# Python SAST with Bandit (run directly with uv for proper pyproject.toml support)
bandit:
name: Python SAST (Bandit)
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
security-events: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Cache uv dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/uv
.venv
key: ${{ runner.os }}-uv-bandit-${{ hashFiles('uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-bandit-
${{ runner.os }}-uv-
- name: Install dependencies
run: uv sync --all-extras --dev
- name: Run Bandit Security Scan
run: |
uv run bandit -r phentrieve api -c pyproject.toml -f sarif -o bandit-results.sarif --severity-level medium --confidence-level medium || true
# Always generate output even if no issues found
if [ ! -s bandit-results.sarif ]; then
echo '{"$schema":"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"Bandit","version":"1.9.2"}},"results":[]}]}' > bandit-results.sarif
fi
- name: Upload Bandit results to GitHub Security
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: bandit-results.sarif
category: bandit
# JavaScript dependency vulnerability scanning
npm-audit:
name: JavaScript Dependency Scan (npm audit)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
working-directory: frontend
run: npm ci
- name: Run npm audit (production dependencies)
working-directory: frontend
run: npm audit --omit=dev --audit-level=critical
- name: Run npm audit (full report)
working-directory: frontend
run: npm audit --audit-level=high || true
# Don't fail on high for dev deps - many false positives
# Security scan summary
security-summary:
name: Security Summary
needs: [pip-audit, bandit, npm-audit]
if: always()
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Check security scan results
run: |
echo "## Security Scan Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Scan | Result |" >> $GITHUB_STEP_SUMMARY
echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| pip-audit (Python deps) | ${{ needs.pip-audit.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Bandit (Python SAST) | ${{ needs.bandit.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| npm audit (JS deps) | ${{ needs.npm-audit.result }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Fail if critical scans failed
if [[ "${{ needs.pip-audit.result }}" == "failure" ]]; then
echo "::error::pip-audit found vulnerabilities in Python dependencies"
exit 1
fi
if [[ "${{ needs.bandit.result }}" == "failure" ]]; then
echo "::error::Bandit found security issues in Python code"
exit 1
fi
# npm-audit failure is warning only (many false positives)
if [[ "${{ needs.npm-audit.result }}" == "failure" ]]; then
echo "::warning::npm audit found issues - review recommended"
fi
echo "::notice::Security scans completed"