From 24659f145dc0a96674488ec9ad89fd41d499cb25 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 27 May 2026 02:58:20 -0700 Subject: [PATCH 1/3] chore: enhance CONTRIBUTING guidelines and add security audit workflow --- .github/workflows/security-audit.yml | 40 ++++++++++++++++++++++++++++ CONTRIBUTING.md | 28 ++++++++++++++++++- requirements-dev.in | 2 +- requirements-dev.lock | 5 ++-- requirements.in | 2 ++ requirements.lock | 3 ++- 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/security-audit.yml diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml new file mode 100644 index 0000000..697020c --- /dev/null +++ b/.github/workflows/security-audit.yml @@ -0,0 +1,40 @@ +name: Security audit + +# Runs on every pull request (no paths-ignore) so dependency scans are not +# skipped when the main CI workflow is skipped for docs-only changes. + +on: + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + pip-audit: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Install uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + python-version: "3.13" + + - name: Cache uv + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: ~/.cache/uv + key: ${{ runner.os }}-uv-pip-audit-${{ hashFiles('requirements.lock', 'requirements-dev.lock') }} + restore-keys: | + ${{ runner.os }}-uv-pip-audit- + ${{ runner.os }}-uv- + + - name: Dependency audit (pip-audit) + run: | + uv venv + uv pip install "pip-audit>=2.10,<3" + uv run pip-audit --desc on -r requirements.lock -r requirements-dev.lock diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0de1bb9..a1c684b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -133,10 +133,36 @@ uv run python benchmarks/compare_to_baseline.py bench.json benchmarks/baselines. **CI:** The [`.github/workflows/benchmarks.yml`](.github/workflows/benchmarks.yml) workflow runs on **`workflow_dispatch`** only, uploads `bench.json` as an artifact, and runs the compare step on success. +## Dependency security audit + +Every pull request runs **[`.github/workflows/security-audit.yml`](.github/workflows/security-audit.yml)** (`pip-audit` against the pinned dependency trees). Unlike the main [CI workflow](.github/workflows/actions.yml), this workflow has **no `paths-ignore`**, so doc-only PRs still get a dependency scan. + +**What is scanned** + +- [`requirements.lock`](requirements.lock) — production / Docker image +- [`requirements-dev.lock`](requirements-dev.lock) — dev and CI (includes `-r requirements.in`) + +**Run locally** (same command as CI, from the repo root): + +```bash +uv venv +uv pip install "pip-audit>=2.10,<3" +uv run pip-audit --desc on -r requirements.lock -r requirements-dev.lock +``` + +If the audit reports a vulnerable package, bump the constraint in [`requirements.in`](requirements.in) or [`requirements-dev.in`](requirements-dev.in), then regenerate locks: + +```bash +uv pip compile requirements.in -o requirements.lock --python-version 3.13 +uv pip compile requirements-dev.in -o requirements-dev.lock --python-version 3.13 +``` + +Commit the updated `.in` and `.lock` files. Prefer fixing versions over long-lived `--ignore-vuln` entries. + ## Other guidelines - **Branching:** Create feature branches from `develop`. Open pull requests against `develop`. See [docs/Development_guideline.md](docs/Development_guideline.md). -- **Code style:** Use Python 3.13 and follow Django and project conventions. Use the project’s logging (`logging.getLogger(__name__)`). Before pushing, run **`uv run pyright`** (with dev deps) for the paths covered by **`pyrightconfig.json`**, and ensure CI’s **lint** / **pyright** / **test** jobs would pass. +- **Code style:** Use Python 3.13 and follow Django and project conventions. Use the project’s logging (`logging.getLogger(__name__)`). Before pushing, run **`uv run pyright`** (with dev deps) for the paths covered by **`pyrightconfig.json`**, and ensure CI’s **lint** / **pyright** / **test** / **Security audit** jobs would pass. - **Database:** Use the Django ORM and migrations. Writes only through the service layer as above. - **Docs:** Update this file (and app `services.py` docstrings) when adding new apps or changing the write rules. After changing `services.py` or `core/protocols.py`, run `python scripts/generate_service_docs.py` and commit the updated `docs/service_api/` files. diff --git a/requirements-dev.in b/requirements-dev.in index caeae51..ebced4a 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -3,7 +3,7 @@ -r requirements.in -pytest>=7.4,<9 +pytest>=9.0.3,<10 pytest-benchmark>=4.0,<6 pytest-django>=4.5,<5 django-stubs>=4.2.7,<5 diff --git a/requirements-dev.lock b/requirements-dev.lock index 5a1fe38..2c59ebf 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -108,8 +108,9 @@ httplib2==0.31.2 # google-auth-httplib2 identify==2.6.19 # via pre-commit -idna==3.14 +idna==3.16 # via + # -r requirements.in # requests # yarl import-linter==2.11 @@ -209,7 +210,7 @@ pyparsing==3.3.2 # via httplib2 pyright==1.1.409 # via -r requirements-dev.in -pytest==8.4.2 +pytest==9.0.3 # via # -r requirements-dev.in # pytest-benchmark diff --git a/requirements.in b/requirements.in index b89105a..01f7c66 100644 --- a/requirements.in +++ b/requirements.in @@ -11,6 +11,8 @@ psycopg[binary]>=3.1,<4 django-environ>=0.11,<1 requests>=2.31,<3 urllib3>=2.0,<3 +# CVE-2026-45409: ensure patched idna (transitive via requests, etc.). +idna>=3.15,<4 discord.py>=2.3.0,<3 python-dateutil>=2.8.0,<3 celery[redis]>=5.3,<6 diff --git a/requirements.lock b/requirements.lock index 883ebb6..488b9a6 100644 --- a/requirements.lock +++ b/requirements.lock @@ -79,8 +79,9 @@ httplib2==0.31.2 # via # google-api-python-client # google-auth-httplib2 -idna==3.14 +idna==3.16 # via + # -r requirements.in # requests # yarl jeepney==0.9.0 From 68ab157391d52e6f2f31f007d3144834e22f3622 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 27 May 2026 07:23:59 -0700 Subject: [PATCH 2/3] chore: update security audit workflow with permissions and credential settings --- .github/workflows/security-audit.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 697020c..ea1e63d 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -13,11 +13,15 @@ concurrency: jobs: pip-audit: + permissions: + contents: read runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Install uv uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 From 1156441fcb440c17de3605993aef5c11c334b62f Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 27 May 2026 16:54:44 -0700 Subject: [PATCH 3/3] docs: update CONTRIBUTING guidelines to specify Linux platform for pip compilation --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a1c684b..e27f871 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -153,8 +153,8 @@ uv run pip-audit --desc on -r requirements.lock -r requirements-dev.lock If the audit reports a vulnerable package, bump the constraint in [`requirements.in`](requirements.in) or [`requirements-dev.in`](requirements-dev.in), then regenerate locks: ```bash -uv pip compile requirements.in -o requirements.lock --python-version 3.13 -uv pip compile requirements-dev.in -o requirements-dev.lock --python-version 3.13 +uv pip compile requirements.in -o requirements.lock --python-version 3.13 --python-platform linux +uv pip compile requirements-dev.in -o requirements-dev.lock --python-version 3.13 --python-platform linux ``` Commit the updated `.in` and `.lock` files. Prefer fixing versions over long-lived `--ignore-vuln` entries.