diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fe471755d..9e08626f6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "dockerfile": "Dockerfile", "context": ".." }, - "postCreateCommand": "pip install -e .[development,docs,casts]", + "postCreateCommand": "pip install -e .[development,docs,casts,cve-audit]", "customizations": { "vscode": { "extensions": [ diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index ae058b519..ac0b30cb7 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -37,6 +37,7 @@ jobs: fulcio.sigstore.dev:443 rekor.sigstore.dev:443 tuf-repo-cdn.sigstore.dev:443 + api.osv.dev:443 - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: @@ -48,6 +49,10 @@ jobs: python-version: '3.x' - name: Install dependencies run: python -m pip install .[wheel] + - name: Audit runtime dependencies for CVEs (C-043) + run: | + pip install .[cve-audit] + pip-audit --vulnerability-service osv . - name: Build a binary wheel and a source tarball run: python3 -m build - name: Generate SBOM for Python distribution diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d01a16535..af370e343 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,8 @@ Release 0.15.0 (unreleased) ============================ +* Implement C-043: add ``pip-audit`` OSV gate to the release workflow; publishing is blocked if + any known vulnerability is found in dfetch's runtime dependencies * Add CRA Compliance Track B: OSCAL 1.1.2 Component Definition mapping all CRA Annex I Part I essential requirements (ECR-a–m) through prEN 40000-1-4 Security Objectives to dfetch controls; covers Part II via prEN 40000-1-3; introduces controls C-043 (release-gate CVE check), C-044 diff --git a/doc/explanation/compliance_track.rst b/doc/explanation/compliance_track.rst index 9f5881c7a..7049097c3 100644 --- a/doc/explanation/compliance_track.rst +++ b/doc/explanation/compliance_track.rst @@ -120,9 +120,9 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi - Status * - **ECR-A** — Be made available on the market without known exploitable vulnerabilities. - SO.VulnerabilityManagementProcess - - :ref:`C-015 `, :ref:`C-016 `, :ref:`C-017 `, :ref:`C-022 ` - - No CVE gate at release time (→ :ref:`C-043 ` planned) - - ⚠ Partial + - :ref:`C-015 `, :ref:`C-016 `, :ref:`C-017 `, :ref:`C-022 `, :ref:`C-043 ` + - — + - ✓ Implemented * - **ECR-B** — Be made available on the market with a secure by default configuration, including the possibility to reset the product to its original state. - SO.SecureDefaultConfiguration - :ref:`C-001 `, :ref:`C-002 ` @@ -355,7 +355,7 @@ Three compliance-only controls address CRA requirements not independently covere **:ref:`C-043 ` — Release-gate CVE check (ECR-a, SO.VulnerabilityManagementProcess → GEC-1)** -dfetch's CI detects vulnerabilities at commit time (:ref:`C-015 `, :ref:`C-016 `, :ref:`C-017 `) but does not gate the release publish on a CVE scan of runtime dependencies. :ref:`C-043 ` (planned) adds ``pip-audit`` or ``osv-scanner`` to the publish workflow. +dfetch's CI detects vulnerabilities at commit time (:ref:`C-015 `, :ref:`C-016 `, :ref:`C-017 `). :ref:`C-043 ` completes the coverage: the publish workflow runs ``pip-audit`` against the project's runtime dependencies via the OSV database and blocks the release if any known vulnerability is found. **:ref:`C-044 ` — Data minimisation policy (ECR-g, SO.DataMinimization → DTM-1)** diff --git a/doc/explanation/control_register.rst b/doc/explanation/control_register.rst index 1346d830a..c12825c5c 100644 --- a/doc/explanation/control_register.rst +++ b/doc/explanation/control_register.rst @@ -201,7 +201,7 @@ requirements not independently surfaced by the risk analysis. C-043 - Release-gate CVE check on runtime dependencies - Compliance-only - - `.github/workflows/python-publish.yml `_ (planned CI addition) + - `.github/workflows/python-publish.yml `_ (Audit runtime dependencies for CVEs step) * - .. _c-044: C-044 diff --git a/pyproject.toml b/pyproject.toml index 7b6c8487c..1095a50e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,6 +108,7 @@ build = [ ] sbom = ["cyclonedx-bom==7.3.0"] wheel = ["build==1.5.0"] +cve-audit = ["pip-audit==2.10.1"] [project.scripts] dfetch = "dfetch.__main__:main" diff --git a/security/compliance_data.py b/security/compliance_data.py index 46e733aa6..c1690de55 100644 --- a/security/compliance_data.py +++ b/security/compliance_data.py @@ -137,12 +137,12 @@ class PartIIRequirement: id="C-043", name="Release-gate CVE check on runtime dependencies", description=( - "Run pip-audit or osv-scanner at release time against dfetch's runtime " - "dependencies; fail the publish workflow if any Critical/High CVE is " - "unresolved." + "Run pip-audit at release time against dfetch's runtime dependencies via " + "the OSV database; the publish workflow fails if any known vulnerability " + "is found in the installed package set." ), threats=["Threat.KnownVulnerabilityExploitation"], - reference=".github/workflows/python-publish.yml (planned CI addition)", + reference=".github/workflows/python-publish.yml (Audit runtime dependencies for CVEs step)", ), Control( id="C-044", @@ -178,12 +178,13 @@ class PartIIRequirement: SOImplementation( so_id="so-vulnerability-management-process", ecr_id="ecr-a", - controls=["C-015", "C-016", "C-017", "C-022"], - gaps=["No CVE gate at release time (→ C-043 planned)"], - status="partially-implemented", + controls=["C-015", "C-016", "C-017", "C-022", "C-043"], + status="implemented", description=( "GEC-1: C-015 (CodeQL), C-016 (dependency-review), C-017 (bandit), " - "C-022 (SBOM) address known-vulnerability detection in CI." + "C-022 (SBOM) address known-vulnerability detection in CI. " + "C-043 (pip-audit OSV gate) blocks release if runtime dependencies " + "carry known vulnerabilities." ), ), # ECR-b: Secure Configuration diff --git a/security/dfetch.component-definition.json b/security/dfetch.component-definition.json index ea116c609..42576c39d 100644 --- a/security/dfetch.component-definition.json +++ b/security/dfetch.component-definition.json @@ -3,7 +3,7 @@ "uuid": "eddc2e8c-a2ae-5a42-8d35-88f5c2af55b2", "metadata": { "title": "dfetch CRA Compliance Component Definition", - "last-modified": "2026-06-15T00:00:00Z", + "last-modified": "2026-06-16T00:00:00Z", "version": "0.15.0", "oscal-version": "1.1.2", "props": [ @@ -61,22 +61,18 @@ "props": [ { "name": "implementation-status", - "value": "partially-implemented" - }, - { - "name": "gaps", - "value": "No CVE gate at release time (\u2192 C-043 planned)" + "value": "implemented" }, { "name": "dfetch-controls", - "value": "C-015, C-016, C-017, C-022" + "value": "C-015, C-016, C-017, C-022, C-043" } ], "statements": [ { "statement-id": "so-vulnerability-management-process-stmt", "uuid": "d07ef2cb-63b5-5c7b-a70e-6530e894f633", - "description": "GEC-1: C-015 (CodeQL), C-016 (dependency-review), C-017 (bandit), C-022 (SBOM) address known-vulnerability detection in CI. Gaps: No CVE gate at release time (\u2192 C-043 planned)" + "description": "GEC-1: C-015 (CodeQL), C-016 (dependency-review), C-017 (bandit), C-022 (SBOM) address known-vulnerability detection in CI. C-043 (pip-audit OSV gate) blocks release if runtime dependencies carry known vulnerabilities." } ] }, @@ -488,7 +484,7 @@ "props": [ { "name": "implementation-status", - "value": "planned" + "value": "implemented" }, { "name": "not-applicable", @@ -503,7 +499,7 @@ { "statement-id": "so-data-minimization-stmt", "uuid": "dda2d3c4-5ef4-56bd-a2a2-923a894ae320", - "description": "DTM-1: C-044 (planned) documents that .dfetch_data.yaml is limited to remote_url (stripped), revision, optional hash, and last_fetch \u2014 each justified by functional necessity. DTM-2: met by design \u2014 dfetch collects no telemetry or optional data. Not applicable: UNM-1, UNM-2 (dfetch processes no personal data requiring user notification); DTM-3 (no optional data processing to configure)" + "description": "DTM-1: C-044 documents that .dfetch_data.yaml is limited to remote_url (stripped), revision, optional hash, and last_fetch \u2014 each justified by functional necessity. DTM-2: met by design \u2014 dfetch collects no telemetry or optional data. Not applicable: UNM-1, UNM-2 (dfetch processes no personal data requiring user notification); DTM-3 (no optional data processing to configure)" } ] }, @@ -655,16 +651,12 @@ "props": [ { "name": "implementation-status", - "value": "planned" + "value": "implemented" }, { "name": "not-applicable", "value": "Compile-time mitigations (CFI, sandboxing) \u2014 not applicable to pure Python" }, - { - "name": "gaps", - "value": "No documented exploit mitigation inventory (\u2192 C-046 planned)" - }, { "name": "dfetch-controls", "value": "C-005, C-007, C-015, C-017, C-046" @@ -674,7 +666,7 @@ { "statement-id": "so-reduce-impact-of-incident-stmt", "uuid": "c6e07d34-53fe-5d62-8e20-14848fc721e1", - "description": "GEC-11: Python interpreter provides ASLR/DEP/stack-canaries (OS-level). dfetch: no eval/exec of remote content; constant-time comparison (C-005); shell=False (C-007); static analysis (C-015, C-017). C-046 (planned) formalises this inventory. Gaps: No documented exploit mitigation inventory (\u2192 C-046 planned) Not applicable: Compile-time mitigations (CFI, sandboxing) \u2014 not applicable to pure Python" + "description": "GEC-11: Python interpreter provides ASLR/DEP/stack-canaries (OS-level). dfetch: no eval/exec of remote content; constant-time comparison (C-005); shell=False (C-007); static analysis (C-015, C-017). C-046 formalises this inventory in doc/explanation/compliance_track.rst. Not applicable: Compile-time mitigations (CFI, sandboxing) \u2014 not applicable to pure Python" } ] }, @@ -887,4 +879,4 @@ ] } } -} +} \ No newline at end of file