JSON-Rohbericht maschinenlesbar
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 911,
"has_wiki": false,
"homepage": null,
"languages": {
"Python": 341238
},
"pushed_at": "2026-07-28T05:55:17Z",
"created_at": "2023-06-02T11:44:10Z",
"owner_type": "Organization",
"updated_at": "2026-07-28T05:54:26Z",
"description": "ESP-IDF Software Bill of Materials Generation Tool",
"is_archived": false,
"is_disabled": false,
"license_spdx": "Apache-2.0",
"default_branch": "master",
"license_spdx_raw": "Apache-2.0",
"primary_language": "Python",
"significant_languages": [
"Python"
]
},
"owner": {
"blog": "http://espressif.com",
"name": "Espressif Systems",
"type": "Organization",
"login": "espressif",
"company": null,
"location": "Shanghai, China",
"followers": 8454,
"avatar_url": "https://avatars.githubusercontent.com/u/9460735?v=4",
"created_at": "2014-10-30T09:42:08Z",
"is_verified": null,
"public_repos": 322,
"account_age_days": 4288
},
"license": {
"state": "standard",
"spdx_id": "Apache-2.0",
"raw_spdx": "Apache-2.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.3.1",
"kind": "patch",
"published_at": "2026-07-28T05:56:24Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2026-07-15T10:37:21Z"
},
{
"tag": "v1.2.0",
"kind": "minor",
"published_at": "2026-06-24T13:24:39Z"
},
{
"tag": "v1.1.0",
"kind": "minor",
"published_at": "2026-06-10T06:14:14Z"
},
{
"tag": "v1.0.1",
"kind": "patch",
"published_at": "2026-01-29T10:46:07Z"
},
{
"tag": "v1.0.0",
"kind": "major",
"published_at": "2026-01-29T07:01:00Z"
},
{
"tag": "v0.21.1",
"kind": "patch",
"published_at": "2025-12-29T12:46:42Z"
},
{
"tag": "v0.21.0",
"kind": "minor",
"published_at": "2025-07-22T07:22:59Z"
},
{
"tag": "v0.20.1",
"kind": "patch",
"published_at": "2025-03-18T11:53:11Z"
},
{
"tag": "v0.20.0",
"kind": "minor",
"published_at": "2025-03-18T09:16:00Z"
},
{
"tag": "v0.19.1",
"kind": "patch",
"published_at": "2024-10-22T13:36:06Z"
},
{
"tag": "v0.19.0",
"kind": "minor",
"published_at": "2024-10-15T12:28:09Z"
},
{
"tag": "v0.18.0",
"kind": "minor",
"published_at": "2024-09-10T13:43:16Z"
},
{
"tag": "v0.17.1",
"kind": "patch",
"published_at": "2024-07-11T11:06:10Z"
},
{
"tag": "v0.17.0",
"kind": "minor",
"published_at": "2024-07-10T08:14:12Z"
},
{
"tag": "v0.16.0",
"kind": "minor",
"published_at": "2024-06-19T10:31:25Z"
},
{
"tag": "v0.15.0",
"kind": "minor",
"published_at": "2024-04-29T10:45:17Z"
}
],
"recent_commits": [
{
"oid": "37f796425e5c477316eed72eebc60644a1a2a9c5",
"body": "change: Update version to 1.3.1\n\nSee merge request espressif/esp-idf-sbom!143",
"is_bot": false,
"headline": "Merge branch 'change/release_v1.3.1' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-28T05:53:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "379666dc82811c304085e2f80abe510963904944",
"body": null,
"is_bot": false,
"headline": "change: Update version to 1.3.1",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-23T11:15:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e8362885d4ccb58175ca1845127653ba9fa402ae",
"body": "fix: recover orphaned sbom manifests of managed components\n\nSee merge request espressif/esp-idf-sbom!140",
"is_bot": false,
"headline": "Merge branch 'fix/orphaned_sbom_manifest' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-23T10:58:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ad2ecc161e21ef3544b1ce1e815c936b02813aab",
"body": "fix: correct CVE-2020-22283 exclusion version range\n\nSee merge request espressif/esp-idf-sbom!142",
"is_bot": false,
"headline": "Merge branch 'fix/cve-2020-22283_version_range' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-23T08:46:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ac6e24012385931d05bf6c6050207186db728dbb",
"body": "The lwip CVE-2020-22283 exclusion was merged with\nversionEndExcluding: '2.2.0', which suppresses the CVE only for\nversions below 2.2.0. That is backwards: it excludes 2.1.3 (and the\nunpatched 2.1.2) while leaving 2.2.0 reported, so the CVE keeps being\nreported as MAYBE on master/v6.0/v5.5/v5.4/v5.3 \n[…]\n the CVE for every\nversion that carries the fix (2.1.3, 2.2.0 and later) while still\nreporting genuinely unpatched pre-2.1.3 versions.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: correct CVE-2020-22283 exclusion version range",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-23T08:27:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8a81137344178d1b87549e806a0b5b4c6a596d8d",
"body": "…4612_cve-2026-63860_cve-2026-15829_cve-2026-63825' into 'master'\n\nchange: adds multiple CVEs to exclude list\n\nSee merge request espressif/esp-idf-sbom!141",
"is_bot": false,
"headline": "Merge branch 'change/exclude_cve-2026-55990_cve-2026-47695_cve-2026-6…",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-23T08:16:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e6be9612155bc6f7b1eee2c91e0b12e890b35e92",
"body": "1. CVE-2026-63825\n2. CVE-2026-15829\n3. CVE-2026-63860\n4. CVE-2026-64612\n5. CVE-2026-47695\n6. CVE-2026-55990\n7. CVE-2024-5290\n8. CVE-2020-22283",
"is_bot": false,
"headline": "change: adds multiple CVEs to exclude list",
"author_name": "Ashish Sharma",
"author_login": "Ashish285",
"committed_at": "2026-07-23T08:00:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "adc67c966e234f6933782de5f2a3c2787d546f91",
"body": "pwalk() skipped an excluded directory's own files but did not stop\nos.walk from descending into it, so only the excluded directory's direct\nfiles were left out while everything nested below it was still yielded.\nAs a result a subpackage's or submodule's nested files were collected for\nthe parent pac\n[…]\nackages. With the\nsubtree now pruned that would find nothing, so walk without excluding\nself.dir and skip the root explicitly instead.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: prune the whole excluded subtree in pwalk",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-22T13:46:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4c20ef3081512c6b3f649d5ddacaa3151f65574d",
"body": "idf-component-manager >= v2.0 re-serializes idf_component.yml from a\npydantic model that does not declare the custom \"sbom\" field, so the\n\"sbom\" section is silently dropped when a component is published (see\nespressif/idf-component-manager commit 54ff963 \"refactor: rewrite with\npydantic\"). The refer\n[…]\ned component manager, its \"sbom\" section is present again and\nthe normal referenced-manifest path (a real subpackage) is used instead.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: recover orphaned sbom manifests of managed components",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-22T12:34:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "054a4b512df681c0827aeb5c3df3e06e76e2a95d",
"body": "When collecting a package's files, the directories of its subpackages\nare excluded so the same files are not counted twice. A virtual package,\nhowever, owns no files (SBOMVirtpackage.get_files returns []), and its\ndirectory is the parent directory of its manifest file -- which, for a\nmanifest placed\n[…]\nat the virtual package is emitted, not the component's\nfile list.\n\nSkip SBOMVirtpackage instances when building the exclude_dirs list.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: do not exclude virtual package dirs from the component files",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-22T12:32:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ebcd86b5e8582d0f6c95fb81d667a7cd65b8c1f2",
"body": "update_manifest() records the origin file of a manifest's \"manifests\"\nlist in the private _embeded_path key, which get_subpackages() later\nreads to build the source location reported for an embedded referenced\nmanifest (and in the duplicate-destination error).\n\nThe \"manifests\" list is filled first-w\n[…]\ne\nwrong origin file.\n\nSet _embeded_path first-wins as well, so it always refers to the same\nsource that supplied the \"manifests\" list.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: keep _embeded_path in sync with the manifests list it describes",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-22T12:31:49Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1de902277f69e7858a13cc31e49a38c217d3a4bd",
"body": "fix: use the component version in the sbom section from idf_component.yml\n\nSee merge request espressif/esp-idf-sbom!139",
"is_bot": false,
"headline": "Merge branch 'fix/idf_component_sbom_version' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-20T05:34:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b528a75df80c8bf22c2a1084b414d4626c167dfc",
"body": "….yml\n\nThe sbom section from idf_component.yml usually has no version key,\nsince the component version is stored at the idf_component.yml root.\nThe section is processed as a standalone manifest, so the {} version\nplaceholder in cpe and purl values had nothing to expand from and the\nsection was broke\n[…]\nenced sbom\nmanifest files, which carry their own version key. This also makes the\nsbom section example documented in the README valid.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: use the component version in the sbom section from idf_component…",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-17T15:34:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ef001141fe4c548ca338e16d9192cd2ba95ce0a1",
"body": "change: Update version to 1.3.0\n\nSee merge request espressif/esp-idf-sbom!138",
"is_bot": false,
"headline": "Merge branch 'change/release_v1.3.0' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-15T09:52:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "73bb6bef172fbcd625b2b209a768b08092b3161e",
"body": null,
"is_bot": false,
"headline": "change: Update version to 1.3.0",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-15T07:59:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bdcdac652505afda4696b9d8e053c0ea375c47de",
"body": "feat: format-neutral SBOM model with multi-format output\n\nCloses IDFGH-17580\n\nSee merge request espressif/esp-idf-sbom!136",
"is_bot": false,
"headline": "Merge branch 'feat/generic_sbom_model' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T12:01:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6cd97566c2a2e26290bf04c8d9882e49c95fd232",
"body": "report.show() ordered records only by CVSS base score, so records that\ntie on score kept their scan (traversal) order. The NO and SKIPPED\ngroups carry no score, so every record in them compared equal and the\nsections were emitted in dependency-graph order rather than sorted,\nmaking the report needle\n[…]\nout\nalphabetically. Every output format (rich table, JSON, CSV, markdown)\nrenders from the same record list, so all are fixed at once.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: sort vulnerability report entries by package within each group",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f02f145d4f9b8bde69c8d14f058405eb1aa7d485",
"body": "The check report summary labeled the affected-package rows \"Packages affect by\n<severity> CVEs\" and \"All packages affect by CVEs\". Correct the grammar to\n\"affected by\".\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: correct \"affect by\" to \"affected by\" in the vulnerability report",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0d5cae46239a1510092c52a84158eba7262f0560",
"body": "The proactive \"querying without an API key is slow\" nudge was emitted from\ninside the per-CPE REST query, so it was drawn on top of the live scan\nprogress bar. Emit the API-key status once up front in the check and\nmanifest-check commands, before their progress bar starts, so the bar stays\nclean.\n\nR\n[…]\nindicate the higher request rate it enables.\n\nFixes: 2cee56cf5958 (\"feat: hint about the NVD API key when scanning online without one\")\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: report NVD API-key status up front and drop the 403 key hint",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9ef09e9755c41969e71415eebe9f12a0a289eb7d",
"body": "The idf.py sbom-create action was hardwired to SPDX tag/value. Add a --format\noption that maps to `esp-idf-sbom create --format`, so it can emit any format\nthe tool supports: spdx-tag-value (default), spdx-json, spdx-json-ld and\ncyclonedx-json, with an optional @version suffix. The default output fi\n[…]\nd,\nso the format table stays the single source of truth. idf_ext imports it lazily\ninside the action, so idf.py startup is unaffected.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: let the idf.py sbom-create wrapper select the output format",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "88c6da370abd20bf1fb1e491b3a928d08426bfdd",
"body": "…inistic\n\npwalk() yielded entries in os.walk()'s filesystem order, so the file\nlistings and subpackage ordering in the generated SBOM (in every format)\ncould differ from run to run. Sort dirs and files in place so the walk is\nstable: dirs.sort() fixes the recursion order and files.sort() the\nper-directory order, making the output byte-stable across runs.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: sort the directory walk so SBOM file and package order is determ…",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9327c8125ca5ffb498010767bd3bbd4e183118e3",
"body": "The hello_world_build fixture copies the example then fullcleans and builds, but\nfullclean keeps any sdkconfig the source tree carries (e.g. from a manual idf.py\nset-target). That made the build target depend on local developer state and could\nbreak tests that assert on IDF_TARGET, such as test_mani\n[…]\nitly with idf.py set-target, which clears the build dir and regenerates\nsdkconfig, so the target no longer depends on the source tree.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "ci: make the hello_world test build target deterministic",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5f34ac8fea8b9966addfce7032c20ba8d43067e2",
"body": "The README presented SPDX tag/value as the only output. Rework it so the SBOM is\ndescribed once, with SPDX and CycloneDX as equal output formats:\n\n- the intro mentions both SPDX and CycloneDX;\n- \"Creating SBOM\" documents the create --format option\n (spdx-tag-value, spdx-json, cyclonedx-json);\n- \"Ch\n[…]\n a CycloneDX column;\n- the cve-exclude-list, purl and license notes reference the format mapping\n instead of naming SPDX tags inline.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "docs: rework the README for format-neutral, multi-format output",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a84fdb697455f4eee5c6e6ff598ba9c0a7f4fb70",
"body": "Add an SPDX 3.0 JSON-LD backend to libsbom/spdx.py: render(sbom, format='json-ld')\n-> SPDX 3.0.1 JSON-LD and parse(text, format='json-ld') -> SBOM. Unlike SPDX 2.x,\nSPDX 3.0 has no tag/value form (JSON-LD is its only serialization) and uses an\nelement/relationship graph instead of flat packages.\n\nTh\n[…]\nmat\ngains spdx-json-ld / spdx-json-ld@3.0.1. Two tests cover it: schema validation against\nthe official schema and a check round-trip.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: add SPDX 3.0 JSON-LD output (create --format spdx-json-ld)",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ff139942fa0814c165d1ba67a789ee6ccd49eaa5",
"body": "Add esp_idf_sbom/libsbom/cyclonedx.py, the CycloneDX backend: render(sbom) ->\nCycloneDX 1.6 JSON and parse(text) -> SBOM. The model maps to CycloneDX components\nplus a dependencies graph; sbom.load() auto-detects CycloneDX, so check accepts a\n.cdx.json SBOM with the same results as SPDX.\n\nThe per-pa\n[…]\nnedx, and check round-trips a CycloneDX SBOM in\ntest_check_sbom_cyclonedx.\n\nCloses https://github.com/espressif/esp-idf-sbom/issues/18\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: add CycloneDX 1.6 JSON output (create --format cyclonedx-json)",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "589637e4888f7ef1f2b588b0a45d63578076b0a2",
"body": "create can now emit SPDX 2.2 JSON in addition to tag/value, selected with --format:\n\n esp-idf-sbom create PD # spdx-tag-value (default)\n esp-idf-sbom create PD --format spdx-json\n\n--format maps through a small {format: (backend, encoding)} table, so a further\nformat (e.g. \n[…]\ndates against the SPDX 2.2 schema via pyspdxtools (test_validate_sbom_json),\nand check round-trips a JSON SBOM (test_check_sbom_json).\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: add SPDX 2.2 JSON output and a create --format option",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "dbdd9088e5403a7701495cf5f0efa115fbc85e0d",
"body": "Rework esp-idf-sbom around a single format-neutral SBOM model instead of building\nSPDX directly. Gathering (project_description.json, manifests, git) populates the\nmodel once; a pluggable SPDX backend renders it to a concrete format and parses\nsuch a format back. All format-agnostic operations run o\n[…]\n\nThis is the preparation that lets additional output formats be added as small,\nself-contained backends without touching the commands.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "refactor: switch to a format-neutral SBOM model",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T11:03:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4e8238cd7e84a2c84e661c2fd2ca3646166ce0b5",
"body": "…master'\n\nchange: adds 4 reported CVEs to exclude list\n\nSee merge request espressif/esp-idf-sbom!137",
"is_bot": false,
"headline": "Merge branch 'change/exclude_cve-2025-55297_and_reported_cves' into '…",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T10:20:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c97a184f5758fbe195bb0c87d92d907f3545c935",
"body": "Keyword hits (CVEs not yet analyzed by NVD) were only checked against\nthe manifest cve-exclude-list, so CPE-scoped entries from the global\nexcluded_cves.yaml never applied to them. This left keyword-matched\nfalse positives, such as CVE-2026-40930 reported for libpng 1.6.58,\nvisible as MAYBE even whe\n[…]\ne CPEs, with manifest entries taking\nprecedence, and use it for keyword-based records in both the SBOM check\nand manifest check flows.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: honor global CPE-scoped exclusions for keyword-matched CVEs",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T08:54:36Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6e2dbfe2ffef47a96d97342ef8b1d1e4517b8f80",
"body": "CVE-2025-55297 (scoped [5.2.6, 5.3)): BluFi example memory overflows,\nfixed on the ESP-IDF 5.2 release line since v5.2.6 (commits\nbf50c0c197af, e65cf7ea2a2b). NVD's affected range for the 5.2 line\n([5.2, 5.3.3)) was assigned before v5.2.6 was released and never\nnarrowed, so the fixed v5.2.6/v5.2.7 r\n[…]\n-2026-53337: Linux kernel bonding driver NULL pointer dereference,\nkeyword-matched against the fmt package. Not related to fmtlib/fmt.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: adds 4 reported CVEs to exclude list",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-07-09T08:03:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4cd3e9fa770a705e87b88f38ef62384df9a63bb2",
"body": "Address IDFGH-17863: missing CVEs, CVSS severity, NA scan, Node 20\n\nCloses IDFGH-17863\n\nSee merge request espressif/esp-idf-sbom!135",
"is_bot": false,
"headline": "Merge branch 'fix/issue_24' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-29T06:17:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "69f6ba696515cdf9824536ebaaa51014818c46d8",
"body": "NVD sometimes records a CVE with the version field set to NA (-), meaning\nthe affected version is unspecified (e.g. a development snapshot or a\ndistro-specific issue). Per the CPE 2.3 matching rules a concrete version\nis disjoint from NA, so such CVEs are never returned for a versioned CPE\nquery and\n[…]\n is not NA,\nkeeping the local-db result consistent with the REST path.\n\nRelated to https://github.com/espressif/esp-idf-sbom/issues/24\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: scan NA (unversioned) CPEs under --extended-scan",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-27T09:25:19Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c7d4fe0e7860af7d5982cc3ab372d9774672f3ce",
"body": "The shared scan-broadening flag was originally added as --name and later\ngot the clearer --extended-scan spelling, with --name/-n kept as\nbackward-compatible aliases. The Click destination, and therefore the\nargs key checked throughout the code, was still 'name', which no longer\nreflects what the fl\n[…]\nME_HELP -> EXTENDED_SCAN_HELP). The --extended-scan, -n and\n--name option strings are unchanged, so the CLI stays backward\ncompatible.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "refactor: rename --extended-scan option dest to extended_scan",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-27T09:06:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "768d644264778cbd1e7f334a19e4de704a18b27a",
"body": "NVD files CVEs for the same software under different vendor names. Mbed\nTLS moved from Arm to the TrustedFirmware project in 2020, and NVD\ncreated the 'trustedfirmware' CPEs on 2026-06-05 and now assigns Mbed\nTLS and TF-PSA-Crypto CVEs under both 'arm' and 'trustedfirmware'. A\npackage whose CPE name\n[…]\nvendor renames, and is a no-op once a\nmanifest already lists both vendors.\n\nCloses https://github.com/espressif/esp-idf-sbom/issues/24\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: add CPE vendor aliases so renamed-vendor CVEs are found",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-26T17:08:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "611721b0a3acff31e65116519f9db668f8bde905",
"body": "create_vulnerable_record() selected the CVSS metric with\nmetrics[first_version][0], i.e. the first entry in the highest-version\nlist. When a CVE carries several CVSS metrics of the same version, that\nfirst entry can be a CNA-provided Secondary score rather than NVD's\nPrimary score, so the report sho\n[…]\nma; it is read defensively so missing data degrades to the\nfallback.\n\nReported in https://github.com/espressif/esp-idf-sbom/issues/24.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: report NVD's Primary CVSS score instead of a Secondary one",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-26T11:35:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8814bc9a9c2d9af0e7bfadef75293696aad33993",
"body": "GitHub deprecated the Node 20 runtime on its Actions runners. Several\nactions in our workflows still ran on Node 20 and emitted the\ndeprecation warning, most visibly the Sync to Jira workflow which runs\nhourly on a schedule. Bump them to their Node 24 versions:\n\n- actions/checkout v4 -> v5 (sync-jir\n[…]\ne action, so neither is affected by the Node 20 runtime\ndeprecation.\n\nReported in https://github.com/espressif/esp-idf-sbom/issues/24.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "ci: fix Node 20 deprecation in GitHub Actions workflows",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-26T10:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0f8f0a221e9693e3ce4948f89f49f79261c3e0bf",
"body": "feat: hint about the NVD API key when scanning online without one\n\nSee merge request espressif/esp-idf-sbom!134",
"is_bot": false,
"headline": "Merge branch 'feat/nvd_apikey_hint' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-26T07:04:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2cee56cf59580bfe4934a06fd25d0f3915f584f4",
"body": "When the online NVD REST API is used without an API key, the scan is slow\nbecause of NVD's rate limit: 5 requests per rolling 30 second window versus\n50 with a key. The only pointer to the key was the reactive hint printed on\na 403, but now that the keyed delay keeps a keyless scan right at the\nrate\n[…]\neffect of an\nAPI key on request pacing is visible.\n\nBased on a user suggestion in\nhttps://github.com/espressif/esp-idf-sbom/issues/23.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: hint about the NVD API key when scanning online without one",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-25T14:36:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2fe739a262cc1e56d4466e71a7fc0487e71e9374",
"body": "SbomLog predated esp-pylib's set_console_options()/set_info_stream() and\nhand-built its own stdout/stderr Rich consoles, duplicating logic the base\nEspLog now provides. Replace that with a single set_console_options() call\nand route the info stream to stderr, keeping the machine-readable reports\non \n[…]\n on stdout.\n\nset_console_options() and set_info_stream() were introduced in esp-pylib\n1.1.0, so bump the dependency floor accordingly.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: simplify SbomLog using esp-pylib set_console_options",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-24T14:50:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7d276473ecd85bf11b9fc78ee90a2a0e447180a5",
"body": "change: Update version to 1.2.0\n\nSee merge request espressif/esp-idf-sbom!133",
"is_bot": false,
"headline": "Merge branch 'change/release_v1.2.0' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-24T13:10:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d46a159ac239b9f843c59e0b4bfcfaff1859b862",
"body": null,
"is_bot": false,
"headline": "change: Update version to 1.2.0",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-24T08:37:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "09104f42d9d2150fe5ebc312ab34ca22799356c5",
"body": "feat: speed up NVD queries when an API key is provided\n\nCloses IDFGH-17853\n\nSee merge request espressif/esp-idf-sbom!132",
"is_bot": false,
"headline": "Merge branch 'feat/nvd_apikey_speedup' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-24T08:23:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cd901891419ce30af79d2fd11e443c3bba227922",
"body": "The NVDAPIKEY environment variable was already sent in the apikey\nrequest header, but nvd_request() always slept six seconds between\nrequests, matching NVD's keyless limit of 5 requests per rolling 30\nsecond window. That fixed delay negated the benefit of a key, whose\nlimit is 50 requests per the sa\n[…]\n nvd_request()\ndocstring, which described a delay the code no longer used.\n\nCloses https://github.com/espressif/esp-idf-sbom/issues/23\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: speed up NVD queries when an API key is provided",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-24T07:14:49Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "17c59b82fd23ca79312217b3be859e59bade849b",
"body": "feat: support repository-local excluded_cves.yaml\n\nCloses IDF-15809\n\nSee merge request espressif/esp-idf-sbom!131",
"is_bot": false,
"headline": "Merge branch 'feat/repo_local_excluded_cves' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-19T06:01:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9c3938d6a177b0f1bfc07eadf4acb37faa6af5e7",
"body": "Load an optional excluded_cves.yaml from the root of a scanned ESP-IDF\ntree and merge its entries into the global exclusion set for that scan.\nIt uses the same format as the upstream excluded_cves.yaml and is\nhonored by both `manifest check` and SBOM generation.\n\nBecause the file lives in the tree i\n[…]\n affected release by version\nalone. Also adds a `path` argument to get_excluded_cves() for loading a\nspecific file, used by the tests.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: support repository-local excluded_cves.yaml",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-17T14:09:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9da507aa818f3ec9ba6f172b55ec8fd75f6ce67b",
"body": "feat: adopt esp-pylib for logging and convert the CLI to rich-click\n\nCloses IDF-15319\n\nSee merge request espressif/esp-idf-sbom!129",
"is_bot": false,
"headline": "Merge branch 'feat/migrate_to_esp_pylib' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-11T10:37:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "558b93b067fe7a13734b80fa66822506f64fe332",
"body": "Collections backed by Python sets (component requirements and their\nSPDX relationships, and the per-file and per-package licenses,\ncopyrights and contributors) were emitted in set-iteration order. That\norder depends on hash randomization, so two runs over the same input\nproduced byte-different outpu\n[…]\ncanonicalizes its result, and\nfilter_packages and the vulnerability report become deterministic once\nthe relationship order is stable.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: make SBOM and report output deterministic",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-10T10:22:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "43f3e479ff931e6c10c1ae5b33561ba034d17fd3",
"body": "Migrate esp-idf-sbom onto the shared esp-pylib library following the\nmigrate-to-esp-pylib workflow.\n\n- libsbom/log.py becomes a thin SbomLog(EspLog) subclass plus a\n module-level compatibility shim, so the rest of the package keeps the\n historical log.X API while all output is routed through esp-p\n[…]\nd\n from ESP-IDF, in favor of esp-pylib log.note.\n- sys.exit diagnostics fold into log.die.\n\nAdd the esp-pylib[cli]>=1.0.0 dependency.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: adopt esp-pylib for logging and convert the CLI to rich-click",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-10T10:22:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f4a1451e2180e847986f3fd736105bb2e75b42ae",
"body": "report.py predated the ruff and esp-pylib migration and was never\nreformatted. Apply ruff format and isort (single-line imports), wrap the\nover-long table caption, drop the stray trailing commas after the\ntable.add_row() summary rows (each silently built a one-tuple, flagged by\nmypy) and refresh the copyright year. No behavior change.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: format report.py and refresh its copyright",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-10T07:30:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "425c57082da6dcdcc130111cda077b1e13263dfc",
"body": "change: Update version to 1.1.0\n\nSee merge request espressif/esp-idf-sbom!130",
"is_bot": false,
"headline": "Merge branch 'change/release_v1.1.0' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-10T06:12:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "429d32887abc78fb7ecc0e66d0e5844ef31ba896",
"body": null,
"is_bot": false,
"headline": "change: Update version to 1.1.0",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-09T15:43:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "745d86ddd3866715c436541721a765e4120c39f9",
"body": "The migration from .cz.toml to pyproject.toml in 65163c9e4364 did not\nport the [tool.commitizen] block verbatim. It set version to 1.0.0 even\nthough the released version is 1.0.1, and rewrote bump_message to a\n\"release $current_version → $new_version\" template.\n\nBecause cz bump updates version_files\n[…]\nge: Update version to $new_version\" bump message.\n\nFixes: 65163c9e4364 (\"change: migrate to pyproject.toml and modernize CI workflows\")\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: correct commitizen config after pyproject migration",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-09T15:43:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "66c7790c29b2310e335b91214c6eef8b15b65973",
"body": "fix: avoid -128-NOTFOUND version for in-tree ESP-IDF components\n\nCloses IDFGH-17739\n\nSee merge request espressif/esp-idf-sbom!128",
"is_bot": false,
"headline": "Merge branch 'fix/git_revision_notfound' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-09T11:12:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ae15a9ba1c0533e59cbe825645ad1968833bb3d9",
"body": "test_purl_end_to_end asserted that pkg:github/espressif/esp-idf@<ver>\nnever appears in the generated SBOM. That held only while the sole\npossible source was the auto-derivation suppressed on in-tree wrapper\ncomponents. ESP-IDF is now emitted as its own SPDX package, and that\npackage legitimately car\n[…]\nackageChecksum, so a plain match over the output is unambiguous.\n\nFixes: 87898b1ed909 (\"feat: emit ESP-IDF as a separate SPDX package\")\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: update test_purl_end_to_end for the ESP-IDF SPDX package",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-08T14:35:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "57028e8e135ab77581faa0af1726cbe4421bf618",
"body": "In-tree ESP-IDF components were emitted with a bogus version in the\ngenerated SBOM:\n\n PackageName: component-nvs_flash\n PackageVersion: -128-NOTFOUND\n\nguess_version() uses project_description.json's git_revision as the\nversion for components living under IDF_PATH. git_revision is ESP-IDF's\nIDF\n[…]\n patched ESP-IDF writes. A valid git_revision is\npassed through unchanged.\n\nCloses https://github.com/espressif/esp-idf-sbom/issues/21\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: avoid -128-NOTFOUND version for in-tree ESP-IDF components",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-08T13:21:34Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "915c45b19bb3147ab2d80bb493d551c41bf2d1ae",
"body": "feat: CPE-scoped CVE exclusions and dedicated ESP-IDF SPDX package\n\nCloses IDF-11420, IDF-8098, IDF-12713, and IDF-15056\n\nSee merge request espressif/esp-idf-sbom!125",
"is_bot": false,
"headline": "Merge branch 'feat/excluded_cves_cpe_scope' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-08T13:07:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "671c08a99fa42e48646c4b917cdec7c82ec41208",
"body": "The ESP-IDF framework package now also emits the NA-versioned firmware\nCPE cpe:2.3:o:espressif:esp32_firmware:-. NVD pins version-independent\nfirmware and silicon issues to this version-less CPE (for example\nCVE-2025-27840), which the versioned esp32_firmware:{ver} CPE cannot\nmatch. Both are now emi\n[…]\nentry only matches the NA probe and cannot\nblanket-suppress versioned findings. An ANY (\"*\") version with no\nbounds is still rejected.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: report version-independent esp32_firmware CVEs",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-08T07:02:42Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ec4ded09b41f0b9ae8b61d0c0e33ebe4f61f030e",
"body": "feat: emit Package URLs (PURL) in generated SBOM\n\nCloses IDF-15701\n\nSee merge request espressif/esp-idf-sbom!126",
"is_bot": false,
"headline": "Merge branch 'feat/purl_support' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-06-01T08:50:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "02fdd7ca9aba44865ff99aab71e6e10f2e82882a",
"body": "fix: restore pyparsing 2.x compatibility in expr.py\n\nCloses IDFGH-17734\n\nSee merge request espressif/esp-idf-sbom!127",
"is_bot": false,
"headline": "Merge branch 'fix/pyparsing_2x_compat' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-31T11:16:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e899bdea7ea565d9abb4bfa24eb1c6ba530a175a",
"body": "Commit 89a64c1febd7 (\"fix: ensure pyparsing usage remains compatible\nwith version 2.2.2 or newer\") converted expr.py to the older camelCase\npyparsing API, but missed two usages originally introduced in\nbdcacd2b2aba (\"feat: allow conditional expressions in manifest files\"):\n\n res = _expr.parse_str\n[…]\nfix: ensure pyparsing usage remains compatible with version 2.2.2 or newer\")\nCloses https://github.com/espressif/esp-idf-sbom/issues/20\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: restore pyparsing 2.x compatibility in expr.py",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-29T09:22:01Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2bb047dc2dfc55014582539cbdeac814a5819ee8",
"body": "expr.py predates the ruff adoption and had not been reformatted yet.\nApply ruff and ruff-format, and let the copyright hook update the SPDX\nyear, on their own, so that the subsequent functional change passes the\npre-commit and CI checks without dragging in unrelated reformatting\nnoise.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: apply ruff formatting and copyright year update to expr.py",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-29T09:21:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "64ab791c09b305211fb7f6c2d57a8bb4f23d28b2",
"body": "Add a \"purl\" manifest field accepted in sbom.yml, sbom-purl in\n.gitmodules and the sbom section of idf_component.yml. Emit it as a\nSPDX PACKAGE-MANAGER ExternalRef alongside the existing SECURITY\ncpe23Type entries:\n\n ExternalRef: PACKAGE-MANAGER purl pkg:github/madler/zlib@1.3.2\n\nPURL and CPE pla\n[…]\nersion\nstring identifies a release name, but only the binary's SHA256\nunambiguously identifies the artifact executed during the build.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: emit Package URLs (PURL) in generated SBOM",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-25T14:58:50Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "dabd9e62b3ebd6d4b83d9eabea7698d62e6770f9",
"body": "Update the \"SPDX SBOM layout\" section to mention the new framework\npackage emitted by esp-idf-sbom create. The framework carries the\nESP-IDF version and the CPEs Espressif uses in NVD advisories\n(application + esp32 hardware + esp32_firmware), and the project\npackage DEPENDS_ON it rather than carrying the ESP-IDF CPE itself.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "docs: document the ESP-IDF framework SPDX package",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T17:32:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a842aa5e49b2f3263fbc4df14d8665b5a9e8701f",
"body": "`esp-idf-sbom manifest check` walks manifest files directly rather\nthan going through project_description.json, so the previous commit's\nSPDXFramework -- which keys on proj_desc['idf_path'] -- does not\napply. Without a manifest representing ESP-IDF itself, scans run at\nthe IDF root miss CVEs filed a\n[…]\nation side, this closes the loop so the\ntwo scan modes report the same set of ESP-IDF-level CVEs when both\nare pointed at an IDF tree.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: inject ESP-IDF framework manifest in manifest check",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T17:03:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "87898b1ed909b15afe7f44a4e7082a0d96f3c06e",
"body": "Previously the espressif:esp-idf CPE was stamped directly onto the\napplication/project SPDX package whenever the project's own manifest\ndid not declare its own CPE. That conflates two different things --\n\"my application\" and \"the framework I built against\" -- and gives no\nhome for the additional ESP\n[…]\nckets had been tracking this same restructuring under\ndifferent framings: IDF-8098, IDF-12713, IDF-15056. All three are now\naddressed.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: emit ESP-IDF as a separate SPDX package",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T17:02:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d09b94026d19a80598d738da1622203f157ac129",
"body": "Add an integration test that pins a custom CPE on the main package's\nmanifest, points SBOM_EXCLUDED_CVES_FILE at a synthetic excluded_cves.yaml\nwith a CPE-scoped entry for that CPE, runs `esp-idf-sbom create`, and\nasserts the CVE and its reason appear in the generated SBOM's per-package\nPackageComme\n[…]\n.\n\nVerifies that the global-to-package merge in spdx.py is wired up\ncorrectly and that the env-var override path in nvd.py is honored.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: add test that CPE-scoped exclusions reach the generated SBOM",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T15:08:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5aee6db25fb6e29dee1bdcf668adfec63be184f5",
"body": "Add an env-var-driven override for the excluded_cves.yaml data source.\nWhen SBOM_EXCLUDED_CVES_FILE points at a file, get_excluded_cves()\nreads it directly and skips both the on-disk cache and the upstream\nfetch. The flow becomes:\n\n 0. SBOM_EXCLUDED_CVES_FILE set -- read it, no cache, no network\n \n[…]\n to inject a known\nexclusion list, but also useful for users maintaining their own\nexcluded_cves.yaml outside the upstream repository.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: support SBOM_EXCLUDED_CVES_FILE env var override",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T15:06:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5f487990d848faf6a3fbd9fb018cddb103ad021b",
"body": "Combined with --local-db, the previous change still left one network\ndependency in place: the excluded_cves.yaml fetch (now disk-cached, but\nthe first run on a fresh host still needs the network to populate it).\n\nAdd a --no-sync-excluded-cves flag on the check, create, and\nmanifest check subcommands\n[…]\n--local-db: NVD data and the\nexclusion file come from different hosts, and a user may legitimately\nwant one offline without the other.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: add --no-sync-excluded-cves option for air-gapped runs",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T14:51:59Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2a26742137dbaa1132cc7b126b98e7836b7ceab1",
"body": "Previously every invocation that consumed excluded_cves.yaml downloaded\nit from GitHub. Within a single run an in-process cache covered repeat\nreads, but back-to-back invocations (CI pipelines, scripted scans) and\nthe SBOM-generation path that now reads the file on every package paid\nthe network cos\n[…]\nhat has run esp-idf-sbom at least once keeps working when\noffline, and runs within the TTL never hit the network for this file\nat all.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: cache excluded_cves.yaml on disk with a TTL",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T14:48:42Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "56e8d03bf5c8adb55df82eb38765dba86327c53e",
"body": "Rewrite test/validate_excluded_cves.py to walk both shapes (string\nvalues, the existing unconditional form, and dict values with `cpes`\nand `reason`, the new CPE-scoped form). Reuse libsbom.CPE.is_cpe_valid\nfor syntax checks on each `cpe` instead of a separate regex, so the\nvalidator stays in sync w\n[…]\nddition to fixed ones\n * `versionStartIncluding` and `versionStartExcluding` are mutually\n exclusive; same for the `End` variants.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: validate the extended excluded_cves.yaml schema",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T14:43:22Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "dd50b89597a42a845b66dadf8037669ce9232daf",
"body": "When emitting a package's cve-exclude-list comment in the SPDX file,\nmerge globally-applicable scoped exclusions for any of the package's\nCPEs with the manifest-level cve-exclude-list. Manifest entries win on\nCVE-ID collision (more specific source).\n\nDownstream consumers of the SBOM see a single uni\n[…]\nnifest or\nfrom the global excluded_cves.yaml is not surfaced separately, since\nboth are authoritative for the package being described.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: include CPE-scoped exclusions in generated SBOM",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T14:43:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3616f3b19d79487523f43ddc0c1e653c8bc57351",
"body": "Wire the new get_excluded_cves_for_cpe() helper into both scan sites in\nsbom.py. For each CPE iteration, merge globally-applicable scoped\nexclusions with the manifest's cve-exclude-list before passing the\ncombined map to report.create_vulnerable_record. Manifest entries win\nwhen both sources carry t\n[…]\nl still passes only the manifest-level excludes,\nsince scoped entries (which key on a CPE) cannot apply when there is no\nCPE in scope.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: apply CPE-scoped exclusions during scan",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T14:42:49Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4951864eaf3f61e02f06691fcf094faac7e484f7",
"body": "So far excluded_cves.yaml could only express \"this CVE is unrelated to\nany Espressif product\". To exclude CVEs that DO affect an Espressif\nproduct but are handled (for instance, patched in specific versions),\nthe only option was a per-component cve-exclude-list inside the\nmanifest, which forces the \n[…]\ny. The next commits wire this\ninto the scan flow and SBOM generation; this commit only introduces\nthe helper and documents the schema.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: extend excluded_cves.yaml schema with CPE-scoped exclusions",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T14:42:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "431840778c1b3355709536ada950fafc2330f5b4",
"body": "Previously, entries in excluded_cves.yaml were consulted only inside\ncheck_keyword and only for unanalyzed CVEs surfaced via keyword search.\nIf NVD ever attributed an unrelated CVE (for example a Linux kernel CVE\nthat incorrectly carries an Espressif CPE) to one of our products, the\nexclusion list h\n[…]\nword. CVEs listed in excluded_cves.yaml are now dropped before\nthey leave the NVD layer, regardless of which entry point matched them.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: filter globally-excluded CVEs at the NVD layer",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-19T14:40:42Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f9d95176e68da7572ddae7704df5bb296c7ecc6f",
"body": "fix: support symlinked component directories\n\nCloses IDFGH-17672\n\nSee merge request espressif/esp-idf-sbom!124",
"is_bot": false,
"headline": "Merge branch 'fix/symlinked_component_dir' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-18T14:08:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e0ed7dd795005dfe43535c874c72da4733b3e44c",
"body": "Add a top-level -V/--version flag to esp-idf-sbom that prints the\npackage version and exits, using argparse's built-in version action.\nSuggested in https://github.com/espressif/esp-idf-sbom/issues/19.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "feat: add --version option to CLI",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-18T11:55:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9a42a1d24220fe7715b284e888c8c2379efe0a52",
"body": "When a component's directory is a symbolic link (or a Windows directory\njunction) pointing into a separate git repo, project_description.json\nrecords the symlink path while `git rev-parse --show-toplevel` returns\nthe resolved upstream path. utils.prelpath() then failed with\nValueError because the tw\n[…]\ncceeds and emits the expected repository URL with the #main\npath fragment.\n\nCloses https://github.com/espressif/esp-idf-sbom/issues/19\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: support symlinked component directories",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-18T11:46:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "44ed2ff74e63f7389b2c712155c44ead288beac2",
"body": "Pre-existing ruff-format adjustments and the copyright year bump that\nthe pre-commit hooks pick up when utils.py is touched. Split out from\nthe upcoming fix so the functional change isn't mixed with formatting.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: apply ruff formatting and copyright year update to utils.py",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-18T11:46:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf39df4651bef2c5666576215237e7f2c6806631",
"body": "change: adds CVE-2026-42587 to exclude list\n\nSee merge request espressif/esp-idf-sbom!122",
"is_bot": false,
"headline": "Merge branch 'change/exclude_cve-2026-42587' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-15T10:55:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "209b26ade1031915f24c37ed155bfd14db2a6fbb",
"body": "fix: filter out CVEs with vulnerable=false CPE matches in REST path\n\nSee merge request espressif/esp-idf-sbom!123",
"is_bot": false,
"headline": "Merge branch 'fix/check_cpe_filter_vulnerable_false' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-15T10:55:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cc3e1ea06030094d1b5d8e9cfaa42565203083db",
"body": "The check_cpe REST path used nvd_request(f'cpeName={cpe}') and returned\nits result verbatim. NVD's cpeName= query returns every CVE that\nreferences the CPE in any configuration, regardless of the per-cpeMatch\nvulnerable flag or version range. CVEs where our CPE is listed only as\na runtime requiremen\n[…]\nth the\ngiven CPE. The is_version_vulnerable function already encodes that\nlogic and operates on data the REST response carries inline.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: filter out CVEs with vulnerable=false CPE matches in REST path",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-15T10:43:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "213ce396c26f9c70e128b71b6822bbb5d6133089",
"body": "Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: adds CVE-2026-42587 to exclude list",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-15T07:03:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bf159df98e33ac4b1467970f08780279d932fd8c",
"body": "change: adds CVE-2026-7210 and CVE-2026-1677 to exclude list\n\nSee merge request espressif/esp-idf-sbom!121",
"is_bot": false,
"headline": "Merge branch 'change/exclude_cve-2026-7210_cve-2026-1677' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-13T07:55:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a0f04e196658deae535ce9e6c12269d187e4fdb3",
"body": null,
"is_bot": false,
"headline": "change: adds CVE-2026-7210 and CVE-2026-1677 to exclude list",
"author_name": "Ashish Sharma",
"author_login": "Ashish285",
"committed_at": "2026-05-13T07:35:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1828735a7731b48ef0c2ec99aa4e7e10398b5475",
"body": "change: adds 6 Lua-related CVEs to exclude list\n\nSee merge request espressif/esp-idf-sbom!119",
"is_bot": false,
"headline": "Merge branch 'change/exclude_lua_unrelated_cves' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-13T07:31:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5a581a818b97bb9dfc61aadfdfb534231c917c3f",
"body": "fix: do not crash on malformed SPDX-License-Identifier\n\nSee merge request espressif/esp-idf-sbom!120",
"is_bot": false,
"headline": "Merge branch 'fix/spdx_malformed_license_parsing' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-13T07:31:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0eb63a63bd61a6762b8ccf31313f0fe1f744ca04",
"body": "Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: adds 6 Lua-related CVEs to exclude list",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-12T06:58:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "600ac111ae464fc092b028b923a8305956bbd172",
"body": "The SPDX file-tag parser had two issues that combined to crash\n`esp_idf_sbom license` on input from upstream third-party files:\n\n1. SPDX_LICENSE_RE greedily captured to end-of-line. When the SPDX\n tag was inside a whole-line comment wrapper (notably Markdown's\n `[//]: # (...)` invisible-comment \n[…]\nDX regex, and guard the\nfallback parse so a genuinely malformed expression warns and skips\nthe file instead of crashing the whole run.\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: do not crash on malformed SPDX-License-Identifier",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-05-12T06:58:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8cf08c2b128aaf22300d848832dadac0398865b2",
"body": "change: adds CVE-2026-7422:7426 to exclude list\n\nSee merge request espressif/esp-idf-sbom!117",
"is_bot": false,
"headline": "Merge branch 'change/exclude_freertos_plus_tcp_cves' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-30T07:54:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "555ea5d63b05a17c7a4f5cab3f7d7a586cd45903",
"body": null,
"is_bot": false,
"headline": "change: adds CVE-2026-7422:7426 to exclude list",
"author_name": "Ashish Sharma",
"author_login": "Ashish285",
"committed_at": "2026-04-30T07:45:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c8b91c5720fa8c7e0cb9180e4d9ed3368876068a",
"body": "fix: decouple test_validate_report_json from NVD analysis state\n\nSee merge request espressif/esp-idf-sbom!118",
"is_bot": false,
"headline": "Merge branch 'fix/test_validate_report_json_returncode' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-30T07:22:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b4c4dcefad0185d4059d3b9faa15e93e8726a3eb",
"body": "The test_validate_report_json test runs `esp_idf_sbom check` against a\nfreshly built hello_world SBOM and validates the resulting JSON report\nagainst report_schema.json. The subprocess was invoked with check=True,\nwhich raises CalledProcessError on any non-zero exit code.\n\nHowever, `esp_idf_sbom che\n[…]\no vulns, 1 = vulns found, anything else =\nfatal error).\n\nApply the same pattern here: drop check=True and assert\nreturncode in [0, 1].\n\nSigned-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "fix: decouple test_validate_report_json from NVD analysis state",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-30T06:25:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a103f337fec6b61259dfe5d94c7b0f62caf001e8",
"body": "…ter'\n\nchange: adds CVE-2026-35469 and CVE-2026-27820 to exclude list\n\nSee merge request espressif/esp-idf-sbom!116",
"is_bot": false,
"headline": "Merge branch 'change/exclude_cve-2026-35469_cve-2026-27820' into 'mas…",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-21T09:03:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "59fed893041d612699b800facd84d2dcdb810d54",
"body": "Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: adds CVE-2026-35469 and CVE-2026-27820 to exclude list",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-21T08:40:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "841d45eeb828e0a792e6d44c4a06a944778ba463",
"body": "change: add CVE-2026-40036 to exclude list\n\nSee merge request espressif/esp-idf-sbom!115",
"is_bot": false,
"headline": "Merge branch 'change/exclude_CVE-2026-40036' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-09T14:29:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "82c35d4f27dca3cd13fef9c8cd15e029850b5f21",
"body": "Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: add CVE-2026-40036 to exclude list",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-09T04:45:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "544ca831cad557f1d32a9fae0672a61474a3b23f",
"body": "…ter'\n\nchange: adds CVE-2026-34608 and CVE-2026-34940 to exclude list\n\nSee merge request espressif/esp-idf-sbom!114",
"is_bot": false,
"headline": "Merge branch 'change/exclude_cve-2026-34608_cve-2026-34940' into 'mas…",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-07T06:37:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b51599bb52838b6d826f875da9fe9c146dcb0d14",
"body": null,
"is_bot": false,
"headline": "change: adds CVE-2026-34608 and CVE-2026-34940 to exclude list",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-07T06:37:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f9155577b59f9a2f7e3d7bcf276965f156f0b60d",
"body": "change: add CVE-2026-5312 to exclude list\n\nSee merge request espressif/esp-idf-sbom!113",
"is_bot": false,
"headline": "Merge branch 'change/exclude_CVE-2026-5312' into 'master'",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-02T06:54:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1c5735cca853f500a2b584077d18621a76cdae90",
"body": "Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>",
"is_bot": false,
"headline": "change: add CVE-2026-5312 to exclude list",
"author_name": "Frantisek Hrbata",
"author_login": "fhrbata",
"committed_at": "2026-04-02T06:44:49Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 17,
"commits_last_year": 158,
"latest_release_at": "2026-07-28T05:56:24Z",
"latest_release_tag": "v1.3.1",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 34,
"days_since_latest_release": 0,
"mean_days_between_releases": 55.2
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 62,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"ecosystem": {
"packages": [
{
"name": "esp-idf-sbom",
"exists": true,
"license": null,
"keywords": [
"espressif",
"embedded",
"spdx",
"sbom",
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Natural Language :: English",
"Operating System :: MacOS :: MacOS X",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Software Development :: Embedded Systems"
],
"ecosystem": "pypi",
"matches_repo": true,
"registry_url": "https://pypi.org/project/esp-idf-sbom/",
"is_deprecated": false,
"latest_version": "1.3.1",
"repository_url": "https://github.com/espressif/esp-idf-sbom",
"versions_count": 29,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": "2023-06-12T14:25:08.186678Z",
"latest_published_at": "2026-07-28T05:57:04.887347Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
}
]
},
"popularity": {
"forks": 4,
"stars": 25,
"watchers": 5,
"fork_history": {
"days": [
{
"date": "2023-08-14",
"count": 1
},
{
"date": "2023-12-04",
"count": 1
},
{
"date": "2024-04-16",
"count": 1
},
{
"date": "2026-07-27",
"count": 1
}
],
"complete": true,
"collected": 4,
"total_forks": 4
},
"star_history": null,
"open_issues_and_prs": 2
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [],
"largest_source_bytes": 74858,
"source_files_sampled": 18,
"oversized_source_files": 1,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"pyproject.toml"
],
"advisories": {
"error": "No resolved dependencies carried a version and a supported ecosystem",
"scope": "repository_graph",
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 4,
"direct_affected_count": 0
},
"ecosystems": [
"pypi"
],
"dependencies": [
{
"name": "PyYAML",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "schema",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "license-expression",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "rich",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "pyparsing",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=2.2.2"
},
{
"name": "esp-pylib",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.1.0"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "esp-pylib",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pyparsing",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "setuptools",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "spdx-tools",
"direct": false,
"version": null,
"ecosystem": "pypi"
}
],
"collected": true,
"truncated": false,
"total_count": 4,
"direct_count": 2,
"indirect_count": 2
}
},
"maintainership": {
"issues": {
"open_prs": 1,
"merged_prs": 2,
"open_issues": 1,
"closed_ratio": 0.95,
"closed_issues": 19,
"closed_unmerged_prs": 1
},
"bus_factor": 1,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "fhrbata",
"commits": 330,
"avatar_url": "https://avatars.githubusercontent.com/u/3449323?v=4"
},
{
"type": "User",
"login": "Ashish285",
"commits": 22,
"avatar_url": "https://avatars.githubusercontent.com/u/40630962?v=4"
},
{
"type": "User",
"login": "dobairoland",
"commits": 10,
"avatar_url": "https://avatars.githubusercontent.com/u/3954250?v=4"
},
{
"type": "User",
"login": "espressif-bot",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/57494357?v=4"
},
{
"type": "User",
"login": "mahavirj",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/902446?v=4"
},
{
"type": "User",
"login": "jakub-kocka",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/46049162?v=4"
}
],
"contributors_sampled": 6,
"top_contributor_share": 0.899
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"create_gh_release.yml",
"release_pypi.yml",
"sync-jira.yml"
],
"has_docs_dir": false,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": true
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 8,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "37f796425e5c477316eed72eebc60644a1a2a9c5",
"ran_at": "2026-07-28T05:58:43Z",
"aggregate_score": 4.9,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-28T05:54:28Z",
"oldest_open_prs": [
{
"number": 27,
"created_at": "2026-07-27T12:46:30Z",
"last_comment_at": null,
"last_comment_author": null
}
],
"last_merged_pr_at": "2026-02-12T11:04:46Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 26,
"created_at": "2026-07-27T12:19:11Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/espressif/esp-idf-sbom",
"host": "github.com",
"name": "esp-idf-sbom",
"owner": "espressif"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"security": 49,
"vitality": 90,
"community": 43,
"governance": 64,
"engineering": 71
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 90,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "excellent",
"name": "Development activity",
"note": null,
"notes": [],
"value": 88,
"inputs": {
"commits_last_year": 158,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 34
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "34/52 weeks with commits",
"points": 23.5,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 34
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "158 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 158
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 92,
"inputs": {
"releases_count": 17,
"latest_release_tag": "v1.3.1",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 55.2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "17 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 17
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~55.2 days",
"points": 19.8,
"status": "partial",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 55.2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 0,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 0 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 0
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 43,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 30,
"inputs": {
"forks": 4,
"stars": 25,
"watchers": 5,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "25 stars",
"points": 22.4,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 25
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "4 forks",
"points": 4,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 4
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "5 watchers",
"points": 3.3,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 5
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 57,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (Apache-2.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "Apache-2.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 64,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 22,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 6,
"top_contributor_share": 0.899
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 90% of commits",
"points": 2.3,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 90
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "6 contributors",
"points": 8.1,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 6
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 70,
"inputs": {
"merged_prs": 2,
"open_issues": 1,
"closed_issues": 19,
"issue_closed_ratio": 0.95,
"closed_unmerged_prs": 1
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "95% of issues closed",
"points": 44.4,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 95
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "2/3 decided PRs merged",
"points": 25.5,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 2,
"decided": 3
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "good",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 80,
"inputs": {
"followers": 8454,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "espressif",
"public_repos": 322,
"account_age_days": 4288
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "8,454 followers of espressif",
"points": 25,
"status": "met",
"details": [
{
"code": "owner_followers",
"params": {
"count": 8454,
"login": "espressif"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "322 public repos, account ~11 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 322
}
},
{
"code": "account_age_years",
"params": {
"years": 11
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"esp-idf-sbom"
],
"ecosystems": "pypi",
"any_deprecated": false,
"min_days_since_publish": 0
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on pypi",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "pypi"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 0 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 0
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "29 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 29
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "good",
"name": "Engineering Quality",
"value": 71,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "excellent",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 92,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": true
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "3 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 3
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 16,
"status": "met",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 9.6,
"status": "met",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "at_risk",
"name": "Documentation",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"topics": [],
"has_wiki": false,
"homepage": null,
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 49,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 49,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 4.9
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 6,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 3
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "at_risk",
"name": "AI Readiness",
"value": 39,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.96,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "96 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 96,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "at_risk",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 33,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": false,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [],
"agent_commit_share": 0,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 11,
"status": "met",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "moderate",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"primary_language": "Python",
"largest_source_bytes": 74858,
"source_files_sampled": 18,
"oversized_source_files": 1
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Python without a type-check config",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_typecheck_config_language",
"params": {
"language": "Python"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "1/18 source files over 60KB",
"points": 51.9,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 18,
"oversized": 1
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"deps.dev does not index pypi:esp-idf-sbom@1.3.1; advisories assessed against the repository dependency graph instead",
"No resolved dependencies carried a version and a supported ecosystem"
],
"report_type": "repository",
"generated_at": "2026-07-28T05:58:51.217619Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/e/espressif/esp-idf-sbom.svg",
"full_name": "espressif/esp-idf-sbom",
"license_state": "standard",
"license_spdx": "Apache-2.0"
}