From 890dbeca8a748722a31e57ebfb7ac956177f5d5b Mon Sep 17 00:00:00 2001 From: 0xsl1m <85326122+0xsl1m@users.noreply.github.com> Date: Sat, 25 Jul 2026 19:24:29 -0500 Subject: [PATCH] Audit every optional dependency stack --- .github/workflows/ci.yml | 43 ++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 7 ++++++ docs/PRODUCTION_READINESS.md | 5 +++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4df8059..59576cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,6 +122,8 @@ jobs: name: dependency audit runs-on: ubuntu-latest timeout-minutes: 10 + outputs: + extras: ${{ steps.optional-dependencies.outputs.extras }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -137,6 +139,47 @@ jobs: -r requirements/container.lock python -m pip_audit --no-deps --disable-pip \ -r requirements/build.lock + - name: Discover optional dependency stacks + id: optional-dependencies + shell: bash + run: | + python - <<'PY' >> "$GITHUB_OUTPUT" + import json + import tomllib + from pathlib import Path + + project = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8")) + extras = sorted(project["project"]["optional-dependencies"]) + print(f"extras={json.dumps(extras, separators=(',', ':'))}") + PY + + optional-dependency-audit: + name: optional dependency audit (${{ matrix.extra }}) + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: dependency-audit + strategy: + fail-fast: false + matrix: + extra: ${{ fromJSON(needs.dependency-audit.outputs.extras) }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.12" + - name: Audit ${{ matrix.extra }} dependency stack + env: + EXTRA: ${{ matrix.extra }} + shell: bash + run: | + set -euo pipefail + requirements_file="$RUNNER_TEMP/shadowshield-extra.txt" + printf '.[%s]\n' "$EXTRA" > "$requirements_file" + python -m pip install --upgrade "pip==26.1.2" "pip-audit==2.10.1" + python -m pip_audit --strict --progress-spinner off \ + -r "$requirements_file" workflow-lint: name: workflow lint diff --git a/CHANGELOG.md b/CHANGELOG.md index e95ce7c..583bb81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to ShadowShield are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Supply chain and CI +- Added a strict, dynamically discovered CI matrix that resolves and audits every + declared optional dependency stack, including development and combined `all` + graphs, so new extras cannot silently bypass vulnerability scanning. + ## [0.6.3] — 2026-07-25 Post-launch reliability, request-intake, observability, performance, and diff --git a/docs/PRODUCTION_READINESS.md b/docs/PRODUCTION_READINESS.md index 5e438a1..f1e3683 100644 --- a/docs/PRODUCTION_READINESS.md +++ b/docs/PRODUCTION_READINESS.md @@ -14,7 +14,7 @@ must be resolved before exposing the optional HTTP control plane publicly. | Correctness | Ready | 320 unit/integration cases; strict mypy; Ruff lint/format; CodeQL extended scanning | | Packaging | Ready | Hash-locked build environment, byte-for-byte repeat build gate, Twine validation, installed-wheel smoke test | | Runtime security | Ready with configuration | Early API-key/Bearer auth, bounded/deadlined body intake, detector-failure policy, restricted CORS, immutable protection floor, non-root read-only container | -| Supply chain | Ready | Digest/SHA-pinned build inputs, PyPI OIDC, exact-green-main release gates, immutable image/evidence handling, pre-push vulnerability gate, anonymous GHCR digest pull, registry-verified SLSA and CycloneDX attestations | +| Supply chain | Ready | Digest/SHA-pinned build inputs, PyPI OIDC, exact-green-main release gates, base/lock/per-extra vulnerability gates, immutable image/evidence handling, anonymous GHCR digest pull, registry-verified SLSA and CycloneDX attestations | | Observability | Ready for single process | Content-free telemetry, detector-error counters, Prometheus endpoint, bounded in-memory event feed | | Detection quality | Beta | Curated adversarial: 100%/0% FPR; blind v1–v3 aggregate: 22.2%/20%; v3: 30%/30%; deepset core: 23.3%/0% | | Scale / HA | Not yet | Counters, events, configuration, and rate limits are process-local | @@ -79,6 +79,8 @@ must be resolved before exposing the optional HTTP control plane publicly. - [x] Make benchmark evidence fail visibly on warmup, readiness, or detector errors and report class-conditional per-slice confusion metrics with 95% Wilson confidence intervals. +- [x] Resolve and vulnerability-audit every declared optional dependency stack + independently in CI, including development and combined `all` graphs. ## P1 — launch procedure (operator-owned) @@ -112,7 +114,6 @@ must be resolved before exposing the optional HTTP control plane publicly. promoted, already-scanned OCI artifacts. 9. Pin optional model revisions, pre-cache them for offline production startup, and bound model-loading time. -10. Add vulnerability-audit matrices for every supported optional dependency stack. ## Go / no-go gates