cra-sentinel 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cra_sentinel-1.0.0/LICENSE +21 -0
- cra_sentinel-1.0.0/PKG-INFO +196 -0
- cra_sentinel-1.0.0/README.md +174 -0
- cra_sentinel-1.0.0/cra_sentinel/__init__.py +9 -0
- cra_sentinel-1.0.0/cra_sentinel/assess/__init__.py +0 -0
- cra_sentinel-1.0.0/cra_sentinel/assess/article14.py +314 -0
- cra_sentinel-1.0.0/cra_sentinel/cli.py +597 -0
- cra_sentinel-1.0.0/cra_sentinel/evidence/__init__.py +0 -0
- cra_sentinel-1.0.0/cra_sentinel/evidence/ledger.py +120 -0
- cra_sentinel-1.0.0/cra_sentinel/exporters/__init__.py +0 -0
- cra_sentinel-1.0.0/cra_sentinel/exporters/csaf.py +185 -0
- cra_sentinel-1.0.0/cra_sentinel/exporters/cyclonedx.py +166 -0
- cra_sentinel-1.0.0/cra_sentinel/exporters/notification.py +86 -0
- cra_sentinel-1.0.0/cra_sentinel/exporters/spdx.py +72 -0
- cra_sentinel-1.0.0/cra_sentinel/model.py +196 -0
- cra_sentinel-1.0.0/cra_sentinel/report/__init__.py +0 -0
- cra_sentinel-1.0.0/cra_sentinel/report/html.py +506 -0
- cra_sentinel-1.0.0/cra_sentinel/scanner/__init__.py +0 -0
- cra_sentinel-1.0.0/cra_sentinel/scanner/core.py +117 -0
- cra_sentinel-1.0.0/cra_sentinel/scanner/cvss.py +93 -0
- cra_sentinel-1.0.0/cra_sentinel/scanner/detectors.py +404 -0
- cra_sentinel-1.0.0/cra_sentinel/scanner/intel.py +281 -0
- cra_sentinel-1.0.0/cra_sentinel/server/__init__.py +0 -0
- cra_sentinel-1.0.0/cra_sentinel/server/app.py +167 -0
- cra_sentinel-1.0.0/cra_sentinel/templates.py +203 -0
- cra_sentinel-1.0.0/cra_sentinel/term.py +67 -0
- cra_sentinel-1.0.0/cra_sentinel/watchtower/__init__.py +6 -0
- cra_sentinel-1.0.0/cra_sentinel/watchtower/commands.py +345 -0
- cra_sentinel-1.0.0/cra_sentinel/watchtower/config.py +106 -0
- cra_sentinel-1.0.0/cra_sentinel/watchtower/dashboard.py +171 -0
- cra_sentinel-1.0.0/cra_sentinel/watchtower/notify.py +242 -0
- cra_sentinel-1.0.0/cra_sentinel/watchtower/runner.py +263 -0
- cra_sentinel-1.0.0/cra_sentinel/watchtower/store.py +395 -0
- cra_sentinel-1.0.0/cra_sentinel.egg-info/PKG-INFO +196 -0
- cra_sentinel-1.0.0/cra_sentinel.egg-info/SOURCES.txt +40 -0
- cra_sentinel-1.0.0/cra_sentinel.egg-info/dependency_links.txt +1 -0
- cra_sentinel-1.0.0/cra_sentinel.egg-info/entry_points.txt +3 -0
- cra_sentinel-1.0.0/cra_sentinel.egg-info/top_level.txt +1 -0
- cra_sentinel-1.0.0/pyproject.toml +35 -0
- cra_sentinel-1.0.0/setup.cfg +4 -0
- cra_sentinel-1.0.0/tests/test_suite.py +439 -0
- cra_sentinel-1.0.0/tests/test_watchtower.py +246 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CRA Sentinel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cra-sentinel
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: EU Cyber Resilience Act compliance scanner: SBOM, actively-exploited detection, Article 14 evidence
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://tomvallat.github.io/cra-sentinel/
|
|
7
|
+
Project-URL: Repository, https://github.com/tomvallat/cra-sentinel
|
|
8
|
+
Project-URL: Issues, https://github.com/tomvallat/cra-sentinel/issues
|
|
9
|
+
Keywords: cra,cyber-resilience-act,sbom,cyclonedx,spdx,csaf,vex,compliance,eu
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Legal Industry
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Security
|
|
17
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# CRA Sentinel
|
|
24
|
+
|
|
25
|
+
**Cyber Resilience Act compliance for products with digital elements.**
|
|
26
|
+
Zero dependencies. One command. Evidence an auditor will accept.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
pip install cra-sentinel
|
|
30
|
+
cra scan . --report cra-report.html --sbom sbom.cdx.json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Why this exists
|
|
36
|
+
|
|
37
|
+
Regulation (EU) 2024/2847 applies to every manufacturer placing a product with
|
|
38
|
+
digital elements on the EU market — including manufacturers established outside
|
|
39
|
+
the EU, and including products already on the market.
|
|
40
|
+
|
|
41
|
+
| Date | Obligation |
|
|
42
|
+
|------|------------|
|
|
43
|
+
| **11 September 2026** | Article 14: report actively exploited vulnerabilities within **24 hours** to ENISA and the national CSIRT, full notification within 72 hours, final report within 14 days of a corrective measure |
|
|
44
|
+
| 11 June 2027 | Conformity assessment provisions |
|
|
45
|
+
| **11 December 2027** | Full application: Annex I essential requirements, CE marking |
|
|
46
|
+
|
|
47
|
+
Most manufacturers cannot comply, for a mundane reason: they have no SBOM, no
|
|
48
|
+
vulnerability-monitoring process, and no record of the decisions they have made.
|
|
49
|
+
The regulation does not require you to be free of vulnerabilities. It requires
|
|
50
|
+
you to **know what is in your product, watch it, decide, and be able to show the
|
|
51
|
+
decision.**
|
|
52
|
+
|
|
53
|
+
That last part is what tools usually skip. A vulnerability scan is not evidence.
|
|
54
|
+
A documented triage decision is.
|
|
55
|
+
|
|
56
|
+
## What it does
|
|
57
|
+
|
|
58
|
+
**Builds the inventory.** Resolves components from npm, PyPI, Go, Cargo, Maven,
|
|
59
|
+
Composer, RubyGems, NuGet — lockfiles preferred over manifests, because the SBOM
|
|
60
|
+
must describe what ships, not what was requested.
|
|
61
|
+
|
|
62
|
+
**Separates "vulnerable" from "actively exploited".** Every finding is enriched
|
|
63
|
+
from OSV.dev, then intersected with the CISA Known Exploited Vulnerabilities
|
|
64
|
+
catalogue. Only that intersection starts an Article 14 clock, and the tool says
|
|
65
|
+
so explicitly rather than drowning you in 200 undifferentiated CVEs.
|
|
66
|
+
|
|
67
|
+
**Computes its own severity.** CVSS v3.1 base scores are calculated locally from
|
|
68
|
+
the vector, validated against the published reference values, because under
|
|
69
|
+
Annex I you must be able to justify your own severity assessment.
|
|
70
|
+
|
|
71
|
+
**Assesses 14 controls against the actual text.** Each one names its article —
|
|
72
|
+
Article 14(1)(a), Annex I Part II(2), Article 13(8) — and reports Pass, Partial,
|
|
73
|
+
Fail, or *Attest* for what no tool can verify. Manual checks are excluded from
|
|
74
|
+
the score rather than silently counted as failures.
|
|
75
|
+
|
|
76
|
+
**Keeps an append-only evidence ledger.** Every triage decision is recorded with
|
|
77
|
+
its rationale, author and timestamp. A `not_affected` verdict is refused without
|
|
78
|
+
a CSAF justification, because an auditor will ask for one.
|
|
79
|
+
|
|
80
|
+
**Exports the four formats that matter.** CycloneDX 1.6 (with VEX analysis
|
|
81
|
+
inline), SPDX 2.3, CSAF 2.0 advisories, and a pre-filled Article 14 notification
|
|
82
|
+
draft so the 24-hour window is spent deciding, not formatting.
|
|
83
|
+
|
|
84
|
+
## Commands
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cra scan . # scan and assess
|
|
88
|
+
cra scan . --report r.html --sbom sbom.cdx.json --csaf advisory.json
|
|
89
|
+
cra scan . --fail-on exploited # CI gate: non-zero if a KEV component ships
|
|
90
|
+
cra scan . --fail-on score --min-score 75
|
|
91
|
+
|
|
92
|
+
cra init --contact security@acme.eu --ci
|
|
93
|
+
# scaffold SECURITY.md, the Article 14 runbook,
|
|
94
|
+
# security.txt and a CI workflow
|
|
95
|
+
|
|
96
|
+
cra triage CVE-2021-44228 --status affected \
|
|
97
|
+
-r "log4j-core is bundled in the firmware; JNDI reachable from the syslog parser" \
|
|
98
|
+
--plan "Upgrade to 2.17.1 in 3.2.2" --target-date 2026-09-24
|
|
99
|
+
|
|
100
|
+
cra triage CVE-2021-45046 --status not_affected \
|
|
101
|
+
--justification vulnerable_code_not_in_execute_path \
|
|
102
|
+
-r "Lookups disabled at build time via log4j2.formatMsgNoLookups"
|
|
103
|
+
|
|
104
|
+
cra ledger --history # the audit trail
|
|
105
|
+
cra notify CVE-2021-44228 # Article 14 early-warning draft
|
|
106
|
+
cra advisory --only-exploited # CSAF 2.0 advisory to publish
|
|
107
|
+
cra watch --fail-on-new # diff against baseline; alert on new exploitation
|
|
108
|
+
cra serve # local dashboard for non-terminal colleagues
|
|
109
|
+
cra deadlines # where you are in the timeline
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Exit codes
|
|
113
|
+
|
|
114
|
+
`0` clean · `1` threshold breached · `2` error. Use `--fail-on` to turn a scan
|
|
115
|
+
into a release gate.
|
|
116
|
+
|
|
117
|
+
## Design decisions worth knowing
|
|
118
|
+
|
|
119
|
+
**Zero dependencies.** Standard library only. It installs inside an air-gapped
|
|
120
|
+
build environment and it will still run in 2031, which matters when the support
|
|
121
|
+
period you declared is five years.
|
|
122
|
+
|
|
123
|
+
**`--offline` is real.** Advisory data is cached to `.cra-sentinel/cache/`. On a
|
|
124
|
+
network failure the scan degrades to the cache and says so in the report rather
|
|
125
|
+
than silently reporting zero findings.
|
|
126
|
+
|
|
127
|
+
**A malformed manifest never aborts a scan.** A compliance scan that crashes on
|
|
128
|
+
one bad `pom.xml` is worse than useless in CI.
|
|
129
|
+
|
|
130
|
+
**The HTML report is one self-contained file.** No CDN, no fonts, no tracking.
|
|
131
|
+
It survives being emailed to a notified body and printed to PDF. Dark and light
|
|
132
|
+
themes, readable at 400px.
|
|
133
|
+
|
|
134
|
+
**Nothing leaves your machine except package coordinates.** Component names and
|
|
135
|
+
versions are sent to OSV.dev to query advisories. No source code, no telemetry,
|
|
136
|
+
no account.
|
|
137
|
+
|
|
138
|
+
## Continuous monitoring
|
|
139
|
+
|
|
140
|
+
A scan you run by hand is not monitoring. `cra watchtower` sweeps a portfolio
|
|
141
|
+
of products on a schedule, records the **moment of awareness** when a component
|
|
142
|
+
becomes actively exploited — the fact from which every Article 14 deadline runs
|
|
143
|
+
— and alerts by email or webhook, escalating until someone acknowledges.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
cra watchtower init
|
|
147
|
+
cra watchtower add "Acme — Gateway 3.2.1" --source https://github.com/acme/gw.git
|
|
148
|
+
cra watchtower run # put this on a timer
|
|
149
|
+
cra watchtower status # what is on the clock right now
|
|
150
|
+
cra watchtower ack acme-gateway-321 CVE-2021-44228 --by tom --note "not affected"
|
|
151
|
+
cra watchtower dashboard # portfolio view
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The awareness timestamp is written **before** delivery is attempted: if SMTP is
|
|
155
|
+
down the alert does not arrive, but the evidence still exists. Deployment units
|
|
156
|
+
for systemd and cron are in `deploy/`.
|
|
157
|
+
|
|
158
|
+
## Troubleshooting
|
|
159
|
+
|
|
160
|
+
**`TLS certificate verification failed` on macOS.** Python installed from
|
|
161
|
+
python.org ships without a populated system trust store. CRA Sentinel falls back
|
|
162
|
+
to `certifi` automatically when it is importable; otherwise run the installer's
|
|
163
|
+
one-time fix:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
/Applications/Python\ 3.x/Install\ Certificates.command
|
|
167
|
+
# or
|
|
168
|
+
pip install certifi
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The scanner never reports a clean result it could not verify — a scan with no
|
|
172
|
+
reachable advisory source is marked **Unverified** in both the terminal and the
|
|
173
|
+
report, and the affected controls report *Attest* rather than *Pass*.
|
|
174
|
+
|
|
175
|
+
**Python version.** Requires 3.10 or later. Tested on 3.10 and 3.14.
|
|
176
|
+
|
|
177
|
+
## Scope and limitations
|
|
178
|
+
|
|
179
|
+
This covers third-party component risk — the part of Annex I that is mechanically
|
|
180
|
+
checkable. It does **not** assess first-party source code, hardware, cryptographic
|
|
181
|
+
implementation, or the organisational measures in Annex I Part I. Checks marked
|
|
182
|
+
*Attest* remain the manufacturer's responsibility, and the tool says so in the
|
|
183
|
+
report rather than implying coverage it does not have.
|
|
184
|
+
|
|
185
|
+
Automated output supports, and does not replace, the technical documentation
|
|
186
|
+
required under Annex VII. It is not legal advice.
|
|
187
|
+
|
|
188
|
+
## Development
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
python3 tests/test_suite.py # 33 tests, offline, no network required
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Licence
|
|
195
|
+
|
|
196
|
+
MIT.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# CRA Sentinel
|
|
2
|
+
|
|
3
|
+
**Cyber Resilience Act compliance for products with digital elements.**
|
|
4
|
+
Zero dependencies. One command. Evidence an auditor will accept.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
pip install cra-sentinel
|
|
8
|
+
cra scan . --report cra-report.html --sbom sbom.cdx.json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Why this exists
|
|
14
|
+
|
|
15
|
+
Regulation (EU) 2024/2847 applies to every manufacturer placing a product with
|
|
16
|
+
digital elements on the EU market — including manufacturers established outside
|
|
17
|
+
the EU, and including products already on the market.
|
|
18
|
+
|
|
19
|
+
| Date | Obligation |
|
|
20
|
+
|------|------------|
|
|
21
|
+
| **11 September 2026** | Article 14: report actively exploited vulnerabilities within **24 hours** to ENISA and the national CSIRT, full notification within 72 hours, final report within 14 days of a corrective measure |
|
|
22
|
+
| 11 June 2027 | Conformity assessment provisions |
|
|
23
|
+
| **11 December 2027** | Full application: Annex I essential requirements, CE marking |
|
|
24
|
+
|
|
25
|
+
Most manufacturers cannot comply, for a mundane reason: they have no SBOM, no
|
|
26
|
+
vulnerability-monitoring process, and no record of the decisions they have made.
|
|
27
|
+
The regulation does not require you to be free of vulnerabilities. It requires
|
|
28
|
+
you to **know what is in your product, watch it, decide, and be able to show the
|
|
29
|
+
decision.**
|
|
30
|
+
|
|
31
|
+
That last part is what tools usually skip. A vulnerability scan is not evidence.
|
|
32
|
+
A documented triage decision is.
|
|
33
|
+
|
|
34
|
+
## What it does
|
|
35
|
+
|
|
36
|
+
**Builds the inventory.** Resolves components from npm, PyPI, Go, Cargo, Maven,
|
|
37
|
+
Composer, RubyGems, NuGet — lockfiles preferred over manifests, because the SBOM
|
|
38
|
+
must describe what ships, not what was requested.
|
|
39
|
+
|
|
40
|
+
**Separates "vulnerable" from "actively exploited".** Every finding is enriched
|
|
41
|
+
from OSV.dev, then intersected with the CISA Known Exploited Vulnerabilities
|
|
42
|
+
catalogue. Only that intersection starts an Article 14 clock, and the tool says
|
|
43
|
+
so explicitly rather than drowning you in 200 undifferentiated CVEs.
|
|
44
|
+
|
|
45
|
+
**Computes its own severity.** CVSS v3.1 base scores are calculated locally from
|
|
46
|
+
the vector, validated against the published reference values, because under
|
|
47
|
+
Annex I you must be able to justify your own severity assessment.
|
|
48
|
+
|
|
49
|
+
**Assesses 14 controls against the actual text.** Each one names its article —
|
|
50
|
+
Article 14(1)(a), Annex I Part II(2), Article 13(8) — and reports Pass, Partial,
|
|
51
|
+
Fail, or *Attest* for what no tool can verify. Manual checks are excluded from
|
|
52
|
+
the score rather than silently counted as failures.
|
|
53
|
+
|
|
54
|
+
**Keeps an append-only evidence ledger.** Every triage decision is recorded with
|
|
55
|
+
its rationale, author and timestamp. A `not_affected` verdict is refused without
|
|
56
|
+
a CSAF justification, because an auditor will ask for one.
|
|
57
|
+
|
|
58
|
+
**Exports the four formats that matter.** CycloneDX 1.6 (with VEX analysis
|
|
59
|
+
inline), SPDX 2.3, CSAF 2.0 advisories, and a pre-filled Article 14 notification
|
|
60
|
+
draft so the 24-hour window is spent deciding, not formatting.
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cra scan . # scan and assess
|
|
66
|
+
cra scan . --report r.html --sbom sbom.cdx.json --csaf advisory.json
|
|
67
|
+
cra scan . --fail-on exploited # CI gate: non-zero if a KEV component ships
|
|
68
|
+
cra scan . --fail-on score --min-score 75
|
|
69
|
+
|
|
70
|
+
cra init --contact security@acme.eu --ci
|
|
71
|
+
# scaffold SECURITY.md, the Article 14 runbook,
|
|
72
|
+
# security.txt and a CI workflow
|
|
73
|
+
|
|
74
|
+
cra triage CVE-2021-44228 --status affected \
|
|
75
|
+
-r "log4j-core is bundled in the firmware; JNDI reachable from the syslog parser" \
|
|
76
|
+
--plan "Upgrade to 2.17.1 in 3.2.2" --target-date 2026-09-24
|
|
77
|
+
|
|
78
|
+
cra triage CVE-2021-45046 --status not_affected \
|
|
79
|
+
--justification vulnerable_code_not_in_execute_path \
|
|
80
|
+
-r "Lookups disabled at build time via log4j2.formatMsgNoLookups"
|
|
81
|
+
|
|
82
|
+
cra ledger --history # the audit trail
|
|
83
|
+
cra notify CVE-2021-44228 # Article 14 early-warning draft
|
|
84
|
+
cra advisory --only-exploited # CSAF 2.0 advisory to publish
|
|
85
|
+
cra watch --fail-on-new # diff against baseline; alert on new exploitation
|
|
86
|
+
cra serve # local dashboard for non-terminal colleagues
|
|
87
|
+
cra deadlines # where you are in the timeline
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Exit codes
|
|
91
|
+
|
|
92
|
+
`0` clean · `1` threshold breached · `2` error. Use `--fail-on` to turn a scan
|
|
93
|
+
into a release gate.
|
|
94
|
+
|
|
95
|
+
## Design decisions worth knowing
|
|
96
|
+
|
|
97
|
+
**Zero dependencies.** Standard library only. It installs inside an air-gapped
|
|
98
|
+
build environment and it will still run in 2031, which matters when the support
|
|
99
|
+
period you declared is five years.
|
|
100
|
+
|
|
101
|
+
**`--offline` is real.** Advisory data is cached to `.cra-sentinel/cache/`. On a
|
|
102
|
+
network failure the scan degrades to the cache and says so in the report rather
|
|
103
|
+
than silently reporting zero findings.
|
|
104
|
+
|
|
105
|
+
**A malformed manifest never aborts a scan.** A compliance scan that crashes on
|
|
106
|
+
one bad `pom.xml` is worse than useless in CI.
|
|
107
|
+
|
|
108
|
+
**The HTML report is one self-contained file.** No CDN, no fonts, no tracking.
|
|
109
|
+
It survives being emailed to a notified body and printed to PDF. Dark and light
|
|
110
|
+
themes, readable at 400px.
|
|
111
|
+
|
|
112
|
+
**Nothing leaves your machine except package coordinates.** Component names and
|
|
113
|
+
versions are sent to OSV.dev to query advisories. No source code, no telemetry,
|
|
114
|
+
no account.
|
|
115
|
+
|
|
116
|
+
## Continuous monitoring
|
|
117
|
+
|
|
118
|
+
A scan you run by hand is not monitoring. `cra watchtower` sweeps a portfolio
|
|
119
|
+
of products on a schedule, records the **moment of awareness** when a component
|
|
120
|
+
becomes actively exploited — the fact from which every Article 14 deadline runs
|
|
121
|
+
— and alerts by email or webhook, escalating until someone acknowledges.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
cra watchtower init
|
|
125
|
+
cra watchtower add "Acme — Gateway 3.2.1" --source https://github.com/acme/gw.git
|
|
126
|
+
cra watchtower run # put this on a timer
|
|
127
|
+
cra watchtower status # what is on the clock right now
|
|
128
|
+
cra watchtower ack acme-gateway-321 CVE-2021-44228 --by tom --note "not affected"
|
|
129
|
+
cra watchtower dashboard # portfolio view
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The awareness timestamp is written **before** delivery is attempted: if SMTP is
|
|
133
|
+
down the alert does not arrive, but the evidence still exists. Deployment units
|
|
134
|
+
for systemd and cron are in `deploy/`.
|
|
135
|
+
|
|
136
|
+
## Troubleshooting
|
|
137
|
+
|
|
138
|
+
**`TLS certificate verification failed` on macOS.** Python installed from
|
|
139
|
+
python.org ships without a populated system trust store. CRA Sentinel falls back
|
|
140
|
+
to `certifi` automatically when it is importable; otherwise run the installer's
|
|
141
|
+
one-time fix:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
/Applications/Python\ 3.x/Install\ Certificates.command
|
|
145
|
+
# or
|
|
146
|
+
pip install certifi
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The scanner never reports a clean result it could not verify — a scan with no
|
|
150
|
+
reachable advisory source is marked **Unverified** in both the terminal and the
|
|
151
|
+
report, and the affected controls report *Attest* rather than *Pass*.
|
|
152
|
+
|
|
153
|
+
**Python version.** Requires 3.10 or later. Tested on 3.10 and 3.14.
|
|
154
|
+
|
|
155
|
+
## Scope and limitations
|
|
156
|
+
|
|
157
|
+
This covers third-party component risk — the part of Annex I that is mechanically
|
|
158
|
+
checkable. It does **not** assess first-party source code, hardware, cryptographic
|
|
159
|
+
implementation, or the organisational measures in Annex I Part I. Checks marked
|
|
160
|
+
*Attest* remain the manufacturer's responsibility, and the tool says so in the
|
|
161
|
+
report rather than implying coverage it does not have.
|
|
162
|
+
|
|
163
|
+
Automated output supports, and does not replace, the technical documentation
|
|
164
|
+
required under Annex VII. It is not legal advice.
|
|
165
|
+
|
|
166
|
+
## Development
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
python3 tests/test_suite.py # 33 tests, offline, no network required
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Licence
|
|
173
|
+
|
|
174
|
+
MIT.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""CRA Sentinel — EU Cyber Resilience Act compliance scanner.
|
|
2
|
+
|
|
3
|
+
Regulation (EU) 2024/2847 obliges manufacturers of products with digital
|
|
4
|
+
elements to inventory their components, handle vulnerabilities, and report
|
|
5
|
+
actively exploited ones within 24 hours. This tool produces the evidence.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "1.0.0"
|
|
9
|
+
__all__ = ["__version__"]
|
|
File without changes
|