diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d5127c7..77f9f25 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -55,7 +55,18 @@ jobs: # citing the upstream issue and the date we plan to revisit. - name: Dependency scan (pip-audit) working-directory: backend - run: uv run pip-audit --strict + run: | + uv run pip-audit --strict \ + --ignore-vuln CVE-2026-69247 \ + --ignore-vuln CVE-2026-69248 \ + --ignore-vuln CVE-2026-69249 + # cryptography 48.0.1 advisories waived 2026-08-03: + # CVE-2026-69248 (fix 49.0.0), CVE-2026-69249 (fix 49.0.0), + # CVE-2026-69247 (fix 50.0.0). + # 48.0.1 is the highest version clerk-backend-api allows (every + # clerk release caps cryptography below 49.0.0), so no forward + # fix is resolvable until clerk relaxes its upper bound. See + # backend/pyproject.toml constraint-dependencies comment. - name: Run tests working-directory: backend diff --git a/.github/workflows/weekly-deps-refresh.yml b/.github/workflows/weekly-deps-refresh.yml index 051be58..643f9e9 100644 --- a/.github/workflows/weekly-deps-refresh.yml +++ b/.github/workflows/weekly-deps-refresh.yml @@ -62,7 +62,11 @@ jobs: run: uv run ruff check - name: Backend dependency scan (pip-audit --strict) working-directory: backend - run: uv run pip-audit --strict + run: | + uv run pip-audit --strict \ + --ignore-vuln CVE-2026-69247 \ + --ignore-vuln CVE-2026-69248 \ + --ignore-vuln CVE-2026-69249 - name: Backend tests working-directory: backend run: uv run pytest -q diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 18dd344..2faf4ea 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -158,8 +158,16 @@ constraint-dependencies = [ "starlette>=1.3.1", "pip>=26.1.2", # cryptography: GHSA-537c-gmf6-5ccf (fixed in 48.0.1). Transitive via - # clerk-backend-api / authlib. Remove once a direct dep's own pin - # clears cryptography 48.0.1. + # clerk-backend-api / authlib. Pinned at 48.0.1 (the highest version + # clerk-backend-api allows — every clerk release caps cryptography + # below 49.0.0). Three further advisories — CVE-2026-69248, + # CVE-2026-69249 (both fixed in 49.0.0) and CVE-2026-69247 (fixed in + # 50.0.0) — landed ~2026-08-03 and affect 48.0.1, but no forward fix + # is resolvable: clerk-backend-api<49.0.0 makes 48.0.1 the ceiling. + # These three are waived in the CI pip-audit step via --ignore-vuln + # (see .github/workflows/deploy.yml) pending clerk relaxing its + # upper bound. Remove the ignore flags + this comment once clerk + # ships a version allowing cryptography >=49.0.0. "cryptography>=48.0.1", # joserfc: CVE-2026-48990 (fixed in 1.6.7). Transitive via # clerk-backend-api. Remove once clerk's own pin clears 1.6.7. @@ -170,4 +178,12 @@ constraint-dependencies = [ # pydantic-settings: GHSA-4xgf-cpjx-pc3j (fixed in 2.14.2). Transitive # via fastmcp. Remove once fastmcp's own pin clears 2.14.2. "pydantic-settings>=2.14.2", + # click: PYSEC-2026-2132 (fixed in 8.3.3). Transitive via uvicorn + # (and any CLI tooling that pulls click). The advisory landed + # ~2026-08-03 and turned pip-audit --strict red even though no code + # changed. Patch bump 8.3.1 → 8.3.3 is API-safe. uv resolves the + # constraint to the latest compatible (8.4.2 at time of writing), + # still well within uvicorn's click range. Remove this line once + # uvicorn's own click pin clears 8.3.3. + "click>=8.3.3", ] \ No newline at end of file diff --git a/backend/uv.lock b/backend/uv.lock index f1d4218..4c40f79 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -11,6 +11,7 @@ resolution-markers = [ [manifest] constraints = [ { name = "authlib", specifier = ">=1.7.1" }, + { name = "click", specifier = ">=8.3.3" }, { name = "cryptography", specifier = ">=48.0.1" }, { name = "idna", specifier = ">=3.15" }, { name = "joserfc", specifier = ">=1.6.7" }, @@ -309,14 +310,14 @@ wheels = [ [[package]] name = "click" -version = "8.3.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, ] [[package]] @@ -1665,8 +1666,8 @@ name = "secretstorage" version = "3.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cryptography", marker = "sys_platform != 'win32'" }, - { name = "jeepney", marker = "sys_platform != 'win32'" }, + { name = "cryptography" }, + { name = "jeepney" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } wheels = [