Skip to content

Commit bcb8fac

Browse files
spoorccclaude
andauthored
doc: restructure security.rst for clarity; remove dfetch check as security claim (#1282)
* doc: restructure security.rst for clarity; remove dfetch check as security claim - Remove the "Security assessment output formats" section — dfetch check's SARIF and Code Climate outputs are CI integration features, not part of dfetch's security model - Fix the Threat Models section: toctree now contains only the two actual threat models; the misleading "each page is generated from Python modules" claim (which did not apply to compliance_track or control_register) is corrected - Give CRA Compliance its own toctree for compliance_track and control_register - Move security_pipeline to a subsection of Further Reading (hidden toctree keeps Sphinx happy); removes it from the main narrative flow - Trim Further Reading: shorter descriptions, remove the EU Blue Guide entry and the Code Climate / CycloneDX / SARIF format references https://claude.ai/code/session_01MoaUFm7mhFxEFuk14NKPh2 * doc: fix factual errors in security/CRA compliance documentation Corrections identified by compliance review against CRA (EU) 2024/2847, BSI TR-03183-1, and ENISA/NIST references: - Article 13(5) misidentification (critical): replace with correct framing — Article 13(5) covers manufacturer documentation obligations, not open-source or voluntary compliance. The note and classification table now state that dfetch has no legal obligation under the CRA and that downstream integrators must fulfil their own Article 13 duties. - Recital 18 imprecision: the opening note now cites Article 3(1) (the operative scope provision) alongside Recital 18 (interpretive context). Recitals are preamble text, not binding law. - Legal basis table: replace "Article 3(14), Recital 18, Article 13(5)" with the correct chain: Article 3(1) (scope), Article 3(14) (open-source software steward definition, for reference), Recital 18. - Voluntary alignment row: remove incorrect Article 13(5) citation; state plainly that the document is voluntary. - "Art. 2(a)-(m)" corrected to "Annex I Part I (a)-(m)": Article 2 of the CRA is the scope article, not the essential requirements. - Part II §4 N/A: rewritten without citing Recital 18 as the operative basis; explains the obligation falls on commercial manufacturers only. - ISO/IEC 27005 vocabulary claim removed: BSI TR-03183-1 is the actual source of the Mitigate/Accept/Transfer vocabulary; ISO/IEC 27005 uses different terminology (Retain/Tolerate/Treat/Share/Terminate). - prEN 40000-1-2 title updated to reflect SDL focus confirmed by CEN/CLC work-programme sources; marked as working title. - OSCAL 1.1.2 pinning noted in all three files: NIST released 1.2.2 in April 2026; the docs now clarify 1.1.2 is the pinned version. https://claude.ai/code/session_01MoaUFm7mhFxEFuk14NKPh2 * doc: add Annex V map; fix ECR-B, ECR-C, ECR-D assessment accuracy CRA Annex V technical documentation map (new section): - Added between Classification Decision and Applicable Standards - Maps each of the six Annex V elements to the corresponding dfetch artifact or section, as a convenience for downstream Article 13 conformity assessments ECR-B SO.SecureDefaultConfiguration gap was blank despite ⚠ Partial: - Documents the actual gap: integrity hash (C-005) is opt-in; manifest entries without an ``integrity`` field are fetched without verification ECR-C SO.UserUpdateNotification — C-040 was wrongly mapped: - C-040 is "test result attestation on source archive", not an update notification mechanism - Reclassified as N/A with rationale: dfetch is a passive CLI tool with no persistent process; proactive in-product notifications are not technically feasible without architectural change - Note below table rewritten: clarifies that SUM-1/SUM-2 are satisfied by PyPI+OIDC publishing and the CVE release gate (C-043), and explains the N/A reasoning for LNM-1 in detail ECR-D SO.AccessControl — framing was misleading: - C-006 (non-interactive VCS) and C-036 (credential redaction) are confidentiality controls, not authentication/authorisation mechanisms - Gap now states explicitly that dfetch has no native access control layer and delegates entirely to the VCS server and host OS - SO.AccessControlReport gap note updated: C-045 detects plaintext transport but does not log events https://claude.ai/code/session_01MoaUFm7mhFxEFuk14NKPh2 * doc: correct SO.UserUpdateNotification — dfetch does check for new versions dfetch check and dfetch environment both call newer_version_available() in dfetch/util/github_version_check.py, which polls the GitHub releases API and notifies the user if a newer release exists (suppressed in CI). - Restore SO.UserUpdateNotification as ✓ Implemented with direct reference to github_version_check.py; note CI suppression in Gaps - Move C-040 (test result attestation) to ECR-A where it belongs: attesting that CI tests passed before release is a vulnerability management control, not an update notification mechanism - Correct the note below the table: replace the wrong "N/A — passive CLI tool" explanation with an accurate description of the check https://claude.ai/code/session_01MoaUFm7mhFxEFuk14NKPh2 * doc: fix six weak/wrong ECR→SO control mappings in compliance_track ECR-E SO.DataTransmittedConfidentiality (C-005 removed): C-005 is an integrity hash, not a confidentiality control. Only C-045 remains; status downgraded to ⚠ Partial since C-045 warns but does not enforce HTTPS/SSH — enforcement is delegated to the VCS client. ECR-E SO.ComAuth (C-003, C-004 removed): C-003 (archive symlink validation) and C-004 (archive member type checks) are archive-extraction safety controls, not channel authentication. They are already correctly placed in ECR-J. SO.ComAuth now references only C-045 with a gap note: server authentication is delegated to the OS trust store and VCS client; status ⚠ Partial. ECR-F SO.DataTransmittedIntegrity (C-003, C-004 → C-005): C-003/C-004 validate archive contents after download — that is archive extraction safety, not transmission integrity. C-005 is the actual end-to-end integrity control (HMAC hash over downloaded archive content, opt-in). Gap updated: C-005 applies to archive sources only; git/svn rely on VCS object integrity and TLS/SSH channel integrity. ECR-I SO.LimitExternalImpact (blank gap filled): ⚠ Partial with no documented gap was inconsistent. Gap now states: no connection timeout or rate limiting on VCS operations. ECR-J SO.ReduceAttackSurface (blank gap filled): ⚠ Partial with no documented gap was inconsistent. Gap now states: no domain/URL-scheme allowlist on manifest remote URLs; no network operation timeout enforced. ECR-L SO.LogSecurityRelevantActivities (C-036 removed): C-036 (persisted-metadata credential redaction) is a data-protection control, not a security logging control. Controls column set to "—"; gap updated to accurately describe the logging situation: no persistent structured log, no audit trail of fetch operations. https://claude.ai/code/session_01MoaUFm7mhFxEFuk14NKPh2 * doc: correct three compliance_track claims against actual code ECR-C SO.UserUpdateNotification — CI suppression scope: The suppression guard (os.environ.get("CI")) is in check.py line 102, not in github_version_check.py. dfetch environment calls newer_version_available() unconditionally with no CI guard. Both the row gap column and the note below the table are corrected. ECR-I SO.LimitExternalImpact — timeout gap scoped to git/svn only: archive.py implements timeouts (15 s reachability, 60 s download via _http_conn). The gap now correctly states that only git and svn subprocess calls have no timeout. ECR-J SO.ReduceAttackSurface — same timeout correction applied. https://claude.ai/code/session_01MoaUFm7mhFxEFuk14NKPh2 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent a5b7fc6 commit bcb8fac

3 files changed

Lines changed: 135 additions & 87 deletions

File tree

doc/explanation/compliance_track.rst

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ CRA Compliance
55

66
.. note::
77

8-
dfetch is **non-commercial open-source software** and is exempt from
9-
mandatory CRA obligations under Recital 18 of Regulation (EU) 2024/2847.
10-
This document is produced voluntarily under Article 13(5) to support
8+
dfetch is **non-commercial open-source software** and falls outside the
9+
mandatory scope of Regulation (EU) 2024/2847 (CRA): it is not placed on the
10+
market in the context of a commercial activity (CRA Article 3(1); Recital 18
11+
provides interpretive context). This document is produced voluntarily to support
1112
downstream integrators who must account for open-source components in
12-
their own conformity assessments.
13+
their own Article 13 conformity assessments.
1314

1415
This page provides three-tier traceability from the CRA Annex I essential
1516
requirements through the prEN 40000-1-4 Security Objectives to the
@@ -21,7 +22,7 @@ concrete dfetch controls or documented gaps::
2122
2223
dfetch control (C-001 … C-046) or documented gap
2324

24-
Machine-readable OSCAL 1.1.2 artifacts are kept alongside the source:
25+
Machine-readable artifacts are kept alongside the source, encoded in OSCAL 1.1.2 (pinned version; NIST released 1.2.2 in April 2026 — migration not yet performed):
2526

2627
- `security/cra_pren_4000014_oscal_catalog.json <https://github.com/dfetch-org/dfetch/blob/main/security/cra_pren_4000014_oscal_catalog.json>`_ — prEN 40000-1-4 catalog
2728
- `security/dfetch.component-definition.json <https://github.com/dfetch-org/dfetch/blob/main/security/dfetch.component-definition.json>`_ — dfetch Component Definition
@@ -56,11 +57,65 @@ Classification Decision
5657
* - CRA classification
5758
- Non-commercial open-source software (Recital 18 exemption)
5859
* - Legal basis
59-
- Article 3(14), Recital 18, Article 13(5) of Regulation (EU) 2024/2847
60+
- CRA Article 3(1) (scope — dfetch is not placed on the market in the context of a commercial activity); Article 3(14) (definition of open-source software steward, for reference); Recital 18 (interpretive context for the treatment of non-commercial FOSS)
6061
* - Mandatory obligations
6162
- None — not a commercial product; no CE marking required
6263
* - Voluntary alignment
63-
- This compliance document is produced voluntarily under Article 13(5) to support downstream integrators who must account for open-source components in their own CRA conformity assessments.
64+
- This compliance document is produced voluntarily — dfetch has no legal obligation under the CRA — to support downstream integrators who must account for open-source components in their own Article 13 conformity assessments.
65+
66+
----
67+
68+
CRA Annex V — Technical Documentation Map
69+
------------------------------------------
70+
71+
Annex V of Regulation (EU) 2024/2847 specifies the minimum content for
72+
a manufacturer's technical documentation. The table below maps each
73+
Annex V element to the corresponding dfetch artifact or section.
74+
Because dfetch is outside mandatory CRA scope, this mapping is provided
75+
as a convenience for downstream integrators conducting their own
76+
Article 13 conformity assessments.
77+
78+
.. list-table::
79+
:header-rows: 1
80+
:widths: 45 55
81+
82+
* - Annex V element
83+
- dfetch artifact / section
84+
85+
* - **1. General description** — intended purpose, product name and version,
86+
manufacturer address
87+
- :doc:`security` § *Product and manufacturer identification*;
88+
:doc:`../reference/manifest` (manifest schema and version field)
89+
90+
* - **2. Design and development** — software architecture; how components
91+
build on or feed into each other
92+
- :doc:`../explanation/architecture` (layer diagram and module overview);
93+
:doc:`security_pipeline` § *Threat model pipeline* (security-relevant
94+
component relationships)
95+
96+
* - **3. Production and monitoring** — build pipeline, dependency
97+
management, CI/CD monitoring
98+
- :doc:`security_pipeline` § *Compliance pipeline* and *Release
99+
attestations*; CI workflows in
100+
`.github/workflows/ <https://github.com/dfetch-org/dfetch/tree/main/.github/workflows>`_
101+
102+
* - **4. Cybersecurity risk assessment** (Article 13(2)) — asset
103+
identification, threat analysis, risk treatment
104+
- :doc:`threat_model_supply_chain` (pre-install lifecycle);
105+
:doc:`threat_model_usage` (runtime invocation);
106+
see also :doc:`security` § *Risk Rating Methodology*
107+
108+
* - **5. Implemented security solutions and applied standards** —
109+
list of harmonised standards applied; where not applied,
110+
description of how each Annex I requirement is met
111+
- This page (§§ *Applicable Standards*, *Part I*, *Part II*);
112+
:doc:`control_register` (all 46 controls with references);
113+
OSCAL Component Definition
114+
`security/dfetch.component-definition.json <https://github.com/dfetch-org/dfetch/blob/main/security/dfetch.component-definition.json>`_
115+
116+
* - **6. EU Declaration of Conformity** (Annex IV)
117+
- Not required. dfetch is outside mandatory CRA scope (see
118+
*Classification Decision* above). No CE marking is affixed.
64119

65120
----
66121

@@ -77,7 +132,7 @@ Applicable Standards
77132
- Scope note
78133
- Gap
79134
* - prEN 40000-1-2
80-
- Cyber Resilience Principles and Risk Management
135+
- Cyber Resilience Principles and Secure Development Lifecycle (working title; subject to change on publication)
81136
- Yes
82137
- Process standard covering risk-based product security across the lifecycle. The Product Security Context (§6.2) is documented in :doc:`security`. The threat models (`tm_supply_chain.py <https://github.com/dfetch-org/dfetch/blob/main/security/tm_supply_chain.py>`_, `tm_usage.py <https://github.com/dfetch-org/dfetch/blob/main/security/tm_usage.py>`_) implement §6.3–§6.6.
83138
- —
@@ -89,7 +144,7 @@ Applicable Standards
89144
* - prEN 40000-1-4
90145
- Generic Security Requirements (draft, indicative publication October 2027)
91146
- Yes
92-
- Primary standard for this document. Maps CRA Annex I Part I Art. 2(a)–(m) to Security Objectives (SO.\*) and Technical Controls (GEC-\*, SUM-\*, etc.). The catalog is included as `security/cra_pren_4000014_oscal_catalog.json <https://github.com/dfetch-org/dfetch/blob/main/security/cra_pren_4000014_oscal_catalog.json>`_.
147+
- Primary standard for this document. Maps CRA Annex I Part I requirements (a)–(m) to Security Objectives (SO.\*) and Technical Controls (GEC-\*, SUM-\*, etc.). The catalog is included as `security/cra_pren_4000014_oscal_catalog.json <https://github.com/dfetch-org/dfetch/blob/main/security/cra_pren_4000014_oscal_catalog.json>`_.
93148
- Standard is in draft; final clause numbering may change.
94149
* - EN 18031-1/2:2024
95150
- Common security requirements for radio equipment (basis of prEN 40000-1-4)
@@ -120,13 +175,13 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
120175
- Status
121176
* - **ECR-A** — Be made available on the market without known exploitable vulnerabilities.
122177
- SO.VulnerabilityManagementProcess
123-
- :ref:`C-015 <c-015>`, :ref:`C-016 <c-016>`, :ref:`C-017 <c-017>`, :ref:`C-022 <c-022>`, :ref:`C-043 <c-043>`
178+
- :ref:`C-015 <c-015>`, :ref:`C-016 <c-016>`, :ref:`C-017 <c-017>`, :ref:`C-022 <c-022>`, :ref:`C-040 <c-040>`, :ref:`C-043 <c-043>`
124179
- —
125180
- ✓ Implemented
126181
* - **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.
127182
- SO.SecureDefaultConfiguration
128183
- :ref:`C-001 <c-001>`, :ref:`C-002 <c-002>`
129-
-
184+
- Integrity hash verification (:ref:`C-005 <c-005>`) is opt-in; manifest entries without an ``integrity`` field are fetched without hash verification by default
130185
- ⚠ Partial
131186
* -
132187
- SO.SecureStartupConfig
@@ -150,8 +205,8 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
150205
- — N/A
151206
* -
152207
- SO.UserUpdateNotification
153-
- :ref:`C-040 <c-040>`
154-
-
208+
- `dfetch/util/github_version_check.py <https://github.com/dfetch-org/dfetch/blob/main/dfetch/util/github_version_check.py>`_
209+
- ``dfetch check`` suppresses the call when ``CI`` is set (`check.py <https://github.com/dfetch-org/dfetch/blob/main/dfetch/commands/check.py>`_ line 102); ``dfetch environment`` calls it unconditionally
155210
- ✓ Implemented
156211
* -
157212
- SO.PostponeUpdates
@@ -161,12 +216,12 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
161216
* - **ECR-D** — Ensure protection from unauthorised access by appropriate control mechanisms including authentication, identity or access management systems, and report on possible unauthorised access.
162217
- SO.AccessControl
163218
- :ref:`C-006 <c-006>`, :ref:`C-036 <c-036>`
164-
-
219+
- dfetch has no native authentication or authorisation layer; access control is fully delegated to the underlying VCS server and host OS. C-006 prevents interactive credential prompts (mitigating credential interception), and C-036 strips credentials from persisted metadata — both are confidentiality controls, not access control mechanisms in the authentication/authorisation sense.
165220
- ⚠ Partial
166221
* -
167222
- SO.AccessControlReport
168223
- :ref:`C-045 <c-045>`
169-
- No persistent log of unauthorised access attempts
224+
- No persistent log of access attempts; C-045 detects and warns on plaintext transport but does not log events
170225
- ⚠ Partial
171226
* - **ECR-E** — Protect the confidentiality of stored, transmitted or otherwise processed data by state-of-the-art mechanisms such as encryption at rest and in transit.
172227
- SO.DataStoredConfidentiality
@@ -180,14 +235,14 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
180235
- ✓ Implemented
181236
* -
182237
- SO.DataTransmittedConfidentiality
183-
- :ref:`C-005 <c-005>`, :ref:`C-045 <c-045>`
184-
-
185-
- ✓ Implemented
238+
- :ref:`C-045 <c-045>`
239+
- C-045 warns on plaintext-scheme URLs but does not refuse to proceed; TLS/SSH confidentiality is provided by the underlying VCS client, not enforced by dfetch itself
240+
- ⚠ Partial
186241
* -
187242
- SO.ComAuth
188-
- :ref:`C-003 <c-003>`, :ref:`C-004 <c-004>`, :ref:`C-045 <c-045>`
189-
-
190-
- ✓ Implemented
243+
- :ref:`C-045 <c-045>`
244+
- Server authentication (TLS certificate verification, SSH host-key checking) is delegated to the OS trust store and VCS client; dfetch does not independently authenticate remote endpoints and cannot enforce authenticated channels when C-045's warning is overridden by the user
245+
- ⚠ Partial
191246
* -
192247
- SO.SecureProvisioning
193248
- :ref:`C-005 <c-005>`
@@ -205,8 +260,8 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
205260
- ✓ Implemented
206261
* -
207262
- SO.DataTransmittedIntegrity
208-
- :ref:`C-003 <c-003>`, :ref:`C-004 <c-004>`
209-
- No end-to-end hash for git/svn transport beyond TLS/SSH channel integrity
263+
- :ref:`C-005 <c-005>`
264+
- C-005 provides end-to-end hash verification for archive sources only (opt-in); git and svn sources rely solely on VCS object integrity (SHA-1/SHA-256 object model) and TLS/SSH channel integrity — no dfetch-level hash verification
210265
- ⚠ Partial
211266
* -
212267
- SO.IntegrityReport
@@ -231,7 +286,7 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
231286
* - **ECR-I** — Minimise the negative impact by the products themselves or connected devices on the availability of services provided by other devices or networks.
232287
- SO.LimitExternalImpact
233288
- :ref:`C-001 <c-001>`, :ref:`C-007 <c-007>`
234-
-
289+
- Archive HTTP operations time out at 15 s (reachability) and 60 s (download) via ``archive.py``; git and svn subprocess calls have no timeout and can stall indefinitely
235290
- ⚠ Partial
236291
* -
237292
- SO.PreventAttackPropagation
@@ -246,7 +301,7 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
246301
* - **ECR-J** — Be designed, developed and produced to limit attack surfaces, including external interfaces.
247302
- SO.ReduceAttackSurface
248303
- :ref:`C-001 <c-001>`, :ref:`C-003 <c-003>`, :ref:`C-004 <c-004>`, :ref:`C-007 <c-007>`, :ref:`C-008 <c-008>`
249-
-
304+
- No domain or URL-scheme allowlist constrains which remote URLs the manifest may reference; git and svn subprocess calls have no timeout (archive HTTP operations time out at 15 s / 60 s)
250305
- ⚠ Partial
251306
* - **ECR-K** — Be designed, developed and produced to reduce the impact of an incident using appropriate exploitation mitigation mechanisms and techniques.
252307
- SO.ReduceImpactOfIncident
@@ -255,8 +310,8 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
255310
- ✓ Implemented
256311
* - **ECR-L** — Provide security related information by recording and monitoring relevant internal activity, including the access to or modification of data, services or functions, with an opt-out mechanism for the user.
257312
- SO.LogSecurityRelevantActivities
258-
- :ref:`C-036 <c-036>`
259-
- No persistent security event log (LGM-2/3/4 gap); No opt-out for logging — dfetch does not log by default
313+
-
314+
- No persistent structured security event log (LGM-1/2/3/4 gap). dfetch prints operational output to stderr but does not retain it, does not record which credentials were used, which files were modified, or when remote access occurred. C-036 ensures credentials are excluded from the operational output but is not a logging control.
260315
- ⚠ Partial
261316
* -
262317
- SO.MonitorSecurityRelevantActivities
@@ -296,11 +351,20 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
296351

297352
.. rubric:: Notes on "Implemented" rows with no control listed
298353

299-
**ECR-C SO.Updateability** — No dfetch-specific control is needed. SUM-1/SUM-2
300-
are satisfied by the PyPI distribution mechanism (``pip install --upgrade dfetch``
301-
and GitHub Releases binary packages). pip's TLS-protected download channel provides
302-
the required secure update path. The update mechanism is the responsibility of the
303-
user's package manager, not of dfetch itself.
354+
**ECR-C SO.Updateability** — SUM-1/SUM-2 require the manufacturer to make security
355+
updates available through a secure channel. dfetch publishes every release to PyPI
356+
(TLS-protected, OIDC-authenticated via :ref:`C-010 <c-010>`) and GitHub Releases
357+
(with release attestations per :ref:`C-039 <c-039>`). The CVE gate (:ref:`C-043 <c-043>`)
358+
blocks release if known vulnerabilities are present in runtime dependencies. Providing
359+
the update *mechanism* is the manufacturer's obligation under SUM-1/SUM-2; delivery
360+
to the end user is the responsibility of the user's package manager.
361+
362+
**ECR-C SO.UserUpdateNotification** — ``dfetch check`` and ``dfetch environment``
363+
both call ``newer_version_available()`` (``dfetch/util/github_version_check.py``),
364+
which polls the GitHub releases API and prints a notice if a newer dfetch release
365+
exists. ``dfetch check`` suppresses the call when the ``CI`` environment variable
366+
is set (``check.py`` line 102: ``if not os.environ.get("CI")``); ``dfetch environment``
367+
does not apply this guard and always performs the check.
304368

305369
**ECR-M SO.SecureDataDeletion** — No dfetch-specific control is needed. DLM-1 is
306370
satisfied by design: dfetch stores no personal data, credentials, or cryptographic
@@ -314,7 +378,7 @@ sufficient to remove all dfetch data; no secure-wipe facility is warranted.
314378
Part II — Vulnerability Handling (prEN 40000-1-3)
315379
-------------------------------------------------
316380

317-
Part II requirements are addressed via prEN 40000-1-3. pii-04 is not applicable under Recital 18.
381+
Part II requirements are addressed via prEN 40000-1-3. Part II §4 (active vulnerability reporting to national CSIRTs and ENISA) is not applicable: this obligation falls on commercial manufacturers placing products on the market, not on non-commercial open-source software outside mandatory CRA scope.
318382

319383
.. list-table::
320384
:header-rows: 1

0 commit comments

Comments
 (0)