Embedded Linux compliance auditor — CRA, Secure Boot, SBOM, CVE tracking
Project description
shipcheck
Embedded Linux compliance auditor for the EU Cyber Resilience Act (CRA). Reads what your Yocto build emits — SBOMs, CVE scan output, signing artefacts, license manifests — and reports whether the image is ready to ship.
Status: pre-release. v0.0.x is the iteration stream; v0.1 is the first publishable cut once pilots 0002 / 0003 / 0004 (core-image-full-cmdline / sato / weston) land.
Install
uv tool install shipcheck
# or
pipx install shipcheck
Quickstart
shipcheck audits the build directory, not the layer sources. Point
it at the directory bitbake writes into (the one that contains
tmp/deploy/, conf/local.conf, etc.):
cd path/to/your/yocto/build
shipcheck init # writes .shipcheck.yaml
shipcheck check --build-dir .
A typical CI invocation:
shipcheck check \
--build-dir "${BUILDDIR}" \
--fail-on high \
--format json > shipcheck-report.json
For the multi-file CRA dossier (evidence report, CVE report, license audit, Annex VII technical doc, Declaration of Conformity, raw scan JSON):
shipcheck check \
--build-dir "${BUILDDIR}" \
--format evidence \
--out shipcheck-dossier/
What it checks
| Check id | What it inspects |
|---|---|
sbom-generation |
SPDX 2.3 documents under tmp/deploy/spdx/ against BSI TR-03183-2; detects SPDX 3.0 / CycloneDX |
cve-tracking |
cve-check, vex.bbclass, and sbom-cve-check JSON under tmp/deploy/images/ |
code-integrity |
UEFI/sbsign signing classes, FIT (U-Boot) signatures, dm-verity images, and IMA/EVM (config + ima-evm-utils package presence) |
image-features |
Insecure IMAGE_FEATURES (e.g. debug-tweaks, empty-root-password, allow-root-login) |
hardening-flags |
Compile-time hardening evidence at global build-config scope (security_flags.inc, SECURITY_CFLAGS, SECURITY_LDFLAGS, FORTIFY/stack-protector/PIE markers) |
license-audit |
tmp/deploy/licenses/<image>/license.manifest against allow/denylist |
yocto-cve-check |
Yocto's tmp/log/cve/cve-summary.json (Kirkstone and Scarthgap schemas) |
vuln-reporting |
Article 14 / Annex I Part II §§4-8 documentation obligations from product.yaml |
CVE findings from cve-tracking and yocto-cve-check are reconciled
into a single finding whose sources lists every scanner that flagged
it.
Known limitations
Pilot 0001 (poky Scarthgap core-image-minimal) validated the v0.1 check set
end-to-end against real bitbake output. The following are documented
limitations, not defects:
vuln-reportingrequiresproduct.yaml- without aproduct.yamlproviding Article 14 / Annex I Part II §§4-8 data (CVD policy, SPoC, support period, update distribution), the check returns SKIP with "product_config_path not configured" whenproduct_config_pathis absent from.shipcheck.yaml, or ERROR with "product.yaml not found" when the path is set but the file does not exist. Supply a validproduct.yamlviaproduct_config_pathin.shipcheck.yamlto exercise the check.code-integrityis config/file-level only - detects signing-class inheritance (uefi-sign,sbsign,image-uefi-sign,secureboot), FIT image signatures (UBOOT_SIGN_ENABLE), dm-verity (DM_VERITY_IMAGE), and IMA/EVM (config flags plusima-evm-utilspackage presence), and flags known test keys. It does NOT perform PE/COFF binary signature verification, PKI chain validation (PK/KEK/DB enrollment), cryptographic verification of FIT or dm-verity artefacts, or IMA xattr verification on the rootfs. Those depths are tracked as roadmap follow-ups.- UEFI Secure Boot positive-path detection requires a vendor BSP -
shipcheck's
code-integrityUEFI detector keys on the class-name patternsuefi-sign,sbsign,image-uefi-sign, andsecurebootinIMAGE_CLASSES. None of those.bbclassfiles ship in upstream poky / meta-arm / meta-security / meta-secure-core; the only upstream-realsecureboot.bbclassis in PHYTEC's vendor BSP (meta-ampliphy). Pilot 0005 confirmed this on a vanilla qemuarm64 build. Genuine positive-path UEFI testing therefore requires either a vendor BSP that ships one of the four classes, or meta-arm'sqemuarm64-securebootMACHINE (which uses a different signing path). hardening-flagsis build-config evidence only - reads global build configuration forsecurity_flags.incinheritance (Signal A) and parsesTUNE_CCARGS/SELECTED_OPTIMIZATIONfor-D_FORTIFY_SOURCE=2/3,-fstack-protector-strong,-fPIE, and-Wl,-z,relro -Wl,-z,now(Signal B). Per-recipe override syntax (TUNE_CCARGS:append:pn-foo) is intentionally skipped - global scope only. It does NOT parse ELF binaries to confirm per-binary hardening, and does NOT consumeimage-buildinfo.bbclassoutput; both are tracked as follow-ups (signal SIG-011).sbom-generationaccepts SPDX 2.x, not only 2.3 - poky Scarthgap'screate-spdxclass emits SPDX 2.2 documents; shipcheck accepts both 2.2 and 2.3 against the BSI TR-03183-2 v2.1.0 field requirements. SPDX 3.0 is detected but not field-validated.cve-trackinglooks for specific Yocto output locations - pilot 0001 surfaced thatcve-trackingandyocto-cve-checkuse different lookup logic; the two checks now share a common CVE-discovery helper and agree on evidence presence. The more reliable path isyocto-cve-check, which readstmp/log/cve/cve-summary.json.
What shipcheck is not
shipcheck organises the evidence your Yocto build already emits and formats it as a CRA-aligned dossier. It does not, and cannot, certify compliance. Specifically:
- Not an official CRA compliance tool. No such tool exists at the time of writing. The regulation does not define one, and Commission mandate M/596 for CRA harmonised standards is still in progress.
- Not a Notified Body or certification authority. Conformity assessment under Annex VIII (for critical products) is a separate, legally defined process. shipcheck has no role in it and does not issue certificates, seals, or attestations.
- Not a replacement for legal review. A compliance determination is a legal judgement based on the regulation, product context, and risk assessment. Lawyers and compliance officers make that call; shipcheck provides inputs.
- Not a replacement for harmonised-standards testing (once M/596 publishes). When harmonised standards are available, conformity with them provides presumption of compliance under Article 27. shipcheck may integrate harmonised-standards checks when they exist; it does not today.
- Not complete coverage of CRA obligations. See the
audits/directory for the coverage verdict per Annex. Process obligations, user-documentation obligations, and several soft-property requirements (Annex I Part I b, e, g, h, i, j, l, m) are partly or wholly out of scope.
An official CRA compliance tool would likely require accreditation under a harmonised standard (ISO/IEC 17025 or CRA-specific), Notified Body affiliation for critical products, and formal harmonised-standards conformance testing once those standards publish. shipcheck sits at the opposite end of the spectrum - lightweight, Yocto-native, open-source, and developer-facing.
Readiness is not compliance
shipcheck check reports a readiness score (0-250). A perfect score
means every registered shipcheck check passed on this build. It does
not mean the product is CRA-compliant. Compliance is a legal judgement
made by the manufacturer, not a tooling verdict.
The readiness score is useful as an internal progress indicator. It
correlates with compliance posture but does not attest it. The
manufacturer's signature on the EU Declaration of Conformity is the
attestation. For the full rationale, see
audits/0001-cra-approach/REPORT.md
§§6-7.
Subcommands
| Command | Purpose |
|---|---|
shipcheck check |
Run the registered checks against a build directory |
shipcheck dossier |
Render a multi-scan trend report from the local history store |
shipcheck docs |
Generate the Annex VII technical documentation draft from history + product.yaml |
shipcheck doc declaration |
Generate the EU Declaration of Conformity (Annex V full or Annex VI simplified) |
shipcheck init |
Write a .shipcheck.yaml scaffold |
shipcheck version |
Print the installed version |
Roadmap
shipcheck ships in capability phases. Each phase bundles a set of checks with the report and evidence plumbing they need.
Shipped
v0.0.3 (2026-04-21) - Phase 1 + CRA evidence layer scaffolding
v0.0.4 (2026-04-24) - vuln-reporting placeholder validation
- Phase 1 — SBOM + CVE + Report.
sbom-generationandcve-trackingchecks; terminal / markdown / JSON / HTML reports; readiness score and--fail-onCI gating;.shipcheck.yamlconfiguration. - Phase 2 — Code integrity, hardening, and CRA evidence layer.
code-integrity(UEFI/sbsign signing-class detection, FIT signatures, dm-verity, IMA/EVM config + package presence),image-features(insecureIMAGE_FEATURESsuch asdebug-tweaks,empty-root-password,allow-root-login), andhardening-flags(compile-time hardening evidence:security_flags.incinheritance plusTUNE_CCARGS/SELECTED_OPTIMIZATIONparsing for FORTIFY_SOURCE, stack-protector, PIE, and RELRO+now flags at global build-config scope) checks. Static CRA requirement catalog withcra_mappingmetadata on every finding,--format evidencerenderer,--out DIRmulti-file dossier,license-auditandyocto-cve-checkchecks, CVE finding reconciliation across scanners, SQLite scan history at.shipcheck/history.db, thedossier,docs, anddoc declarationsubcommands, and avuln-reportingcheck covering Article 14 / Annex I Part II §§4-8 documentation obligations.
Pilot: see pilots/0001-poky-scarthgap-min/REPORT.md.
v0.0.5 (2026-04-29) - code-integrity merge + image-features + hardening-flags
- Merged
secure-boot+image-signinginto a singlecode-integritycheck covering UEFI Secure Boot, signed FIT, dm-verity, and IMA/EVM. - Added
image-featurescheck detecting insecureIMAGE_FEATURESentries (debug-tweaks,allow-empty-password, etc.). - Added
hardening-flagscheck detecting compile-time hardening evidence at global build-config scope (security_flags.incinheritance +TUNE_CCARGS/SELECTED_OPTIMIZATIONparsing). - Pilot 0005 validated the three new checks against a real qemuarm64 / poky-scarthgap / core-image-minimal build.
Pilot (code-integrity merge of secure-boot + image-signing): see pilots/0005-code-integrity-and-hardening/REPORT.md.
Pilot (image-features check): see pilots/0005-code-integrity-and-hardening/REPORT.md.
Pilot (hardening-flags check): see pilots/0005-code-integrity-and-hardening/REPORT.md.
Planned
- Phase 3 — Update mechanism + OP-TEE. Detect capsule update / swupdate / RAUC and verify signed updates; OP-TEE integration, measured boot, TPM.
- Phase 3.5 — OCI attestation + kernel hardening. OCI container SBOM
attestation via
image-oci; kernel hardening configs (FORTIFY_SOURCE, STACKPROTECTOR, KASLR);harvest.jsonexport. - Phase 4 — CI integration. GitLab CI and GitHub Actions templates, SARIF output for the GitHub Security tab, shared history aggregation across runs.
- Phase 5 — Web dashboard. FastAPI backend on top of the history store and dossier output; audit-facing share view; self-hostable.
Depth follow-ups
Open improvements to existing checks rather than new phases:
- SPDX 3.0 and CycloneDX full field validation
- Secure Boot PE/COFF binary signature verification
- Secure Boot PKI chain validation (PK / KEK / DB enrollment)
- CI pipeline signing-step detection in
.gitlab-ci.yml/ GitHub workflows - Hardening-flags Signals C+D and per-recipe overrides
(
image-buildinfo.bbclassparsing, ELF artifact verification,TUNE_CCARGS:append:pn-foo-style overrides). Tracked as signal SIG-011. product.yamlcode_integrityblock + validation (manufacturer declares the chosen integrity strategy:fit_dm_verity,uefi_secure_boot,ota_server_signed,ima_evm, orotherwith rationale;code-integritycheck accepts the declared strategy as evidence for Annex I Part I §f). Tracked as signal SIG-012.
Configuration
Per-check configuration lives in .shipcheck.yaml. See the scaffold
emitted by shipcheck init for the full surface; the most common
sections are cve.suppress, license_audit.allowlist/denylist,
yocto_cve.summary_path, and history.enabled.
A product.yaml (referenced by product_config_path) supplies the
manufacturer / support-period / CVD information consumed by
vuln-reporting, the Annex VII generator, and the Declaration of
Conformity generator.
CRA rule catalog
The rules shipcheck implements are part of a broader catalog
maintained by the OpenSSF Global Cyber Policy WG:
cra-yocto-rules.md.
Each rule names the shipcheck check that implements it (or roadmap
for gaps).
License
Apache-2.0. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shipcheck-0.0.5.tar.gz.
File metadata
- Download URL: shipcheck-0.0.5.tar.gz
- Upload date:
- Size: 77.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1775e4a71f9bfeb5e1ced0f2d856bfaffed91a8e58dec0f7e94bab6c98c9a93
|
|
| MD5 |
736a49b5d56966bbc67e0b66fd0a8183
|
|
| BLAKE2b-256 |
3eb34b9b828553717630f5ae49c9c518721bda5acc6cd648d406bd1a8ce15750
|
Provenance
The following attestation bundles were made for shipcheck-0.0.5.tar.gz:
Publisher:
publish.yml on jetm/shipcheck
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shipcheck-0.0.5.tar.gz -
Subject digest:
d1775e4a71f9bfeb5e1ced0f2d856bfaffed91a8e58dec0f7e94bab6c98c9a93 - Sigstore transparency entry: 1406103257
- Sigstore integration time:
-
Permalink:
jetm/shipcheck@d9487933d1a64f9d7e42aa97c776ed4dc9e5f875 -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/jetm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d9487933d1a64f9d7e42aa97c776ed4dc9e5f875 -
Trigger Event:
push
-
Statement type:
File details
Details for the file shipcheck-0.0.5-py3-none-any.whl.
File metadata
- Download URL: shipcheck-0.0.5-py3-none-any.whl
- Upload date:
- Size: 103.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d0993aa684e96725d25aa6f685e9bc828585b733ad753e64063af9dcfcb893d
|
|
| MD5 |
5f3519e8b17837025dec1a69cfcc5a1c
|
|
| BLAKE2b-256 |
b5918f7fb4a7e3d76371c84b43bab23a14277b330afe9d33dc3b6f35528388f0
|
Provenance
The following attestation bundles were made for shipcheck-0.0.5-py3-none-any.whl:
Publisher:
publish.yml on jetm/shipcheck
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shipcheck-0.0.5-py3-none-any.whl -
Subject digest:
7d0993aa684e96725d25aa6f685e9bc828585b733ad753e64063af9dcfcb893d - Sigstore transparency entry: 1406103330
- Sigstore integration time:
-
Permalink:
jetm/shipcheck@d9487933d1a64f9d7e42aa97c776ed4dc9e5f875 -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/jetm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d9487933d1a64f9d7e42aa97c776ed4dc9e5f875 -
Trigger Event:
push
-
Statement type: