feat(ci): add pip-audit dependency vulnerability scanning to CI/CD

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-21 21:17:15 +00:00
parent a2658cb018
commit ac51f7206a
6 changed files with 66 additions and 12 deletions
+29 -4
View File
@@ -55,13 +55,38 @@ jobs:
run: ruff format --check app/ tests/
# ══════════════════════════════════════════════════════════════════════════
# Stage 2: Tests & Type Checking (run in parallel after lint passes)
# Stage 2a: Dependency Vulnerability Scan (runs in parallel with lint)
# ══════════════════════════════════════════════════════════════════════════
dependency-scan:
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 pip-audit
run: pip install pip-audit>=2.7.0
- name: Run pip-audit on production dependencies
run: pip-audit -r requirements.txt --desc on
- name: Run pip-audit on dev dependencies
run: pip-audit -r requirements-dev.txt --desc on
# ══════════════════════════════════════════════════════════════════════════
# Stage 2b: Tests & Type Checking (run in parallel after lint passes)
# ══════════════════════════════════════════════════════════════════════════
test:
name: Tests
runs-on: ubuntu-latest
needs: [lint] # Wait for lint to pass before running tests
needs: [lint, dependency-scan] # Wait for lint and dependency scan before running tests
services:
redis:
image: redis:7
@@ -128,7 +153,7 @@ jobs:
mypy:
name: Mypy
runs-on: ubuntu-latest
needs: [lint] # Wait for lint to pass before running type checks
needs: [lint, dependency-scan] # Wait for lint and dependency scan before running type checks
steps:
- name: Checkout Code
uses: actions/checkout@v4
@@ -153,7 +178,7 @@ jobs:
build:
name: Build & Push Docker Image
runs-on: ubuntu-latest
needs: [test, lint, mypy]
needs: [test, lint, mypy, dependency-scan]
if: github.event_name == 'push'
steps:
+28 -2
View File
@@ -291,11 +291,17 @@ Tests are organized using pytest markers:
Tests run automatically in GitHub Actions for all pull requests. The CI workflow is organized in stages:
**Stage 1: Ruff Lint & Format** (runs first)
**Stage 1: Ruff Lint & Format** (runs first, in parallel with dependency scan)
- Checks code style, formatting, and basic security issues
- Must pass before tests run
**Stage 2: Tests & Type Checking** (runs after lint passes)
**Stage 1b: Dependency Vulnerability Scan** (runs in parallel with lint)
- Runs `pip-audit` against `requirements.txt` and `requirements-dev.txt`
- Fails the build if any known vulnerabilities are detected
- Checks the OSV and PyPA advisory databases
- Runs independently at the same time as Stage 1 so it does not add to total pipeline time
**Stage 2: Tests & Type Checking** (runs after lint and dependency scan both pass)
| Job | Tool | What it checks |
|--------|--------|--------------------------------------|
@@ -339,6 +345,26 @@ ruff format app/ tests/
**Note:** The pre-commit hooks and CI pipeline will automatically check (and optionally fix) these for you.
### Dependency Vulnerability Scanning
DocuElevate uses **pip-audit** to scan dependencies for known security vulnerabilities. The CI pipeline runs this automatically and **blocks builds** if any vulnerabilities are found.
To run locally before pushing:
```bash
# Scan production dependencies
pip-audit -r requirements.txt --desc on
# Scan all dependencies (including dev)
pip-audit -r requirements-dev.txt --desc on
```
If pip-audit is not installed, add it with:
```bash
pip install pip-audit
```
## Project Structure
```
+3 -3
View File
@@ -246,7 +246,7 @@ ftp = ftplib.FTP() # nosec B321 - Plaintext FTP intentional when configured
### Dependency Management
- ✅ Version pinning for security-critical packages (authlib, starlette)
- ✅ Advisory database checks integrated into development workflow
- ⏳ TODO: Add automated dependency vulnerability scanning in CI/CD ([#171](https://github.com/christianlouis/DocuElevate/issues/171))
- ✅ Automated dependency vulnerability scanning in CI/CD via pip-audit ([#171](https://github.com/christianlouis/DocuElevate/issues/171))
### Authentication & Secrets
- ✅ Strong validation for SESSION_SECRET (minimum 32 characters)
@@ -265,8 +265,8 @@ ftp = ftplib.FTP() # nosec B321 - Plaintext FTP intentional when configured
-**COMPLETED:** Bandit (Python security linter) audit completed
-**COMPLETED:** Bandit integrated into CI pipeline (fails on high/medium severity issues)
-**COMPLETED:** CodeQL security scanning enabled in GitHub Actions
- **TODO:** Add dependency vulnerability scanning (Safety, pip-audit) to CI ([#171](https://github.com/christianlouis/DocuElevate/issues/171))
- **TODO:** Make dependency scans blocking (fail on critical issues) ([#171](https://github.com/christianlouis/DocuElevate/issues/171))
- **COMPLETED:** pip-audit dependency vulnerability scanning added to CI ([#171](https://github.com/christianlouis/DocuElevate/issues/171))
- **COMPLETED:** Dependency scans are blocking (fail build when vulnerabilities detected) ([#171](https://github.com/christianlouis/DocuElevate/issues/171))
### Code Security
- ✅ Authentication required on all sensitive endpoints (@require_login decorator)
+2 -1
View File
@@ -217,7 +217,7 @@ DeepSource provided:
**Analysis:**
- Would duplicate CodeQL for security scanning
- Would duplicate Dependabot for dependency vulnerabilities
- Would duplicate Dependabot + pip-audit for dependency vulnerabilities
- Current tools provide adequate coverage
- Not needed at this time
@@ -231,6 +231,7 @@ DeepSource provided:
| Security Linting | Bandit | Ruff | ✅ Consolidated |
| Code Quality | Pylint, DeepSource | Ruff | ✅ Consolidated |
| Security Scanning | CodeQL, DeepSource | CodeQL | ✅ De-duplicated |
| Dependency Vulnerabilities | None | pip-audit | ✅ Added |
| Type Checking | Mypy | Mypy | ✅ Kept (unique) |
| Testing | pytest | pytest | ✅ Kept (unique) |
| Coverage | Codecov | Codecov | ✅ Kept (unique) |
+3 -2
View File
@@ -10,11 +10,12 @@ The CI workflow (`.github/workflows/tests.yaml`) runs automatically on every pus
| Job | Tool | Purpose | Enforced |
|--------|--------|---------------------------------------------|----------|
| `test` | pytest | Unit/integration tests with coverage | ✅ |
| `lint` | Ruff | Fast Python linter (replaces Flake8, Black, isort, Bandit) | ✅ |
| `dependency-scan` | pip-audit | Dependency vulnerability scanning against OSV/PyPA advisories | ✅ |
| `test` | pytest | Unit/integration tests with coverage | ✅ |
| `mypy` | mypy | Static type checking | ✅ |
All three jobs start **in parallel** as soon as the workflow is triggered. No job depends on or waits for any other job.
`lint` and `dependency-scan` start **in parallel** at the beginning of the pipeline — neither depends on the other. `test` and `mypy` run only after both have passed.
> **Note:** DocuElevate uses Ruff, a modern all-in-one Python linter that consolidates the functionality of Flake8, Black, isort, and Bandit. This streamlined approach reduces CI complexity while maintaining code quality and security standards.
+1
View File
@@ -22,6 +22,7 @@ types-requests>=2.31.0
types-paramiko>=3.0.0
# Security scanning (Ruff includes most security checks from bandit)
pip-audit>=2.7.0 # Dependency vulnerability scanning against OSV/PyPA advisory databases
# Pre-commit hooks
pre-commit>=3.6.0