ESP-IDF SBOM Tool (esp-idf-sbom)
The esp-idf-sbom tool creates Software bill of materials (SBOM) files in the Software Package Data Exchange (SPDX) and CycloneDX formats for applications generated by the Espressif IoT Development Framework (ESP-IDF). It also allows to check generated SBOM files for know vulnerabilities against the National Vulnerability Database (NVD) based on the Common Platform Enumeration (CPE) provided in the SBOM.
Table of Contents
- Required ESP-IDF versions
- Installation
- Creating SBOM
- Checking vulnerabilities
- Excluding CVEs
- Usage example
- SBOM layout
- Output formats
- Manifest file
- Licenses and Copyrights
- Return Values
- Resources
Required ESP-IDF versions
All release branches of currently supported ESP-IDF versions allow to generate the SBOM file.
| ESP-IDF version | branch with SBOM support | commits |
|---|---|---|
| 4.3 | release/v4.3 | befb32b45bc9314b48c29624f9a2c2ef30e34260 |
| f1eef50947ab5770ae4d904c07615e7acab06002 | ||
| 4.4 | release/v4.4 | ee505a996045c3657711c3d70c58af8dd48b1426 |
| 53f271ce108d6fa99cf92d59fe9b9dcc4b8fb45b | ||
| 5.0 | release/v5.0 | 30735b33efabd6cf038bcb258b674cf828ad5ecf |
| 9156bbb55c920d6704329975311c331b931ed6bc | ||
| 5.1 | release/v5.1 | 0f781c718c8548cd2b0e41a30e1814f1c6ed93a2 |
| 03162bb276d4155760e8aa839020f0587f5ef599 | ||
| latest | master |
Older versions, e.g. v5.0.2, do not have the required code merged and the following error
message will be printed.
E: Project description file "build/project_description.json" does not support SBOM generation. Please see the list of IDF versions required by esp-idf-sbom.
If you see this error message and want to try esp-idf-sbom, you can
-
switch to the release branch for version you are using. For example
release/v5.0if you are usingv5.0.2. -
use future ESP-IDF versions to experiment with esp-idf-sbom.
-
use
git-cherry-pickand apply commits for your release from the table above. For example forv5.0.2use$ git cherry-pick 30735b33efabd6cf038bcb258b674cf828ad5ecf 9156bbb55c920d6704329975311c331b931ed6bc
Installation
Currently esp-idf-sbom is not integrated into ESP-IDF and needs to by installed separately from Python Package Index (PyPI) with
pip install esp-idf-sbom
After installation the esp-idf-sbom command should be available or the esp_idf_sbom
python module can be used with
python -m esp_idf_sbom
Creating SBOM
The application has to be built before the SBOM file can be created. This step should not be required in the future once esp-idf-sbom is integrated into ESP-IDF.
The SBOM file can be created with
esp-idf-sbom create <project description file>
The project description file is a path to the project_description.json file, which
is by default created by the ESP-IDF build system in the project's build directory.
The generated SBOM file is printed to the standard output stream by default or can be
saved in a file if the --output-file option is used.
The output format is selected with the --format option. A bare name selects the
latest spec version esp-idf-sbom supports for that format; a specific version can be
pinned with an @version suffix (e.g. spdx-json@2.2). The supported values are:
spdx-tag-value,spdx-tag-value@2.2- SPDX 2.2 tag/value (default)spdx-json,spdx-json@2.2- SPDX 2.2 JSONspdx-json-ld,spdx-json-ld@3.0.1- SPDX 3.0 JSON-LDcyclonedx-json,cyclonedx-json@1.6- CycloneDX 1.6 JSON
A bare name always points to the latest supported version and may advance on a major
esp-idf-sbom release (a breaking change), so pin @version when you need reproducible
output.
For example esp-idf-sbom create --format cyclonedx-json -o sbom.cdx.json build/project_description.json.
Checking vulnerabilities
Vulnerabilities are checked based on the Common Platform Enumeration (CPE) information
included in the SBOM file for the SBOM packages. While checking for vulnerabilities, only packages
with direct or indirect relationship to the project package are examined. For example if mbedtls
component is compiled, due to component dependecies, but it's actually not linked into the
final binary, it will be by default presented in the SBOM file, but it will not be reachable
from the root project package and hence it will not be checked for vulnerabilities.
The reason for this is to avoid possible false positives, because such packages
have no direct impact on the resulting application. This can be changed with the --check-all-packages
option. If used, all packages in the SBOM file will be checked for possible vulnerabilities
regardless their relationships to the application binary.
SBOM file generated by the esp-idf-sbom tool can be checked for known vulnerabilities with
esp-idf-sbom check [SBOM file]
If SBOM file is not provided, the standard input stream is used. The SBOM file may be in any format esp-idf-sbom can produce (SPDX tag/value, SPDX JSON, SPDX 3.0 JSON-LD or CycloneDX JSON); the format is detected automatically.
The default report format consists of multiple tables:
- Report summary
- Packages with Identified Vulnerabilities
- Packages with Possible Vulnerabilities
- Packages with Excluded Vulnerabilities
- Packages with No Identified Vulnerabilities
- Packages without CPE and Keyword Information
The output format may be changed with the --format option, which supports exporting
the report into json, csv or markdown format.
If NVD reports that a CVE is in CISA's Known Exploited Vulnerabilities (KEV) catalog, this information is included in the report.
If package is not vulnerable to a specific CVE, it can be added to the manifest cve-exclude-list list and checker will not report it as identified vulnerability, but as excluded vulnerability.
When the --extended-scan option is applied with the check command, the
checker uses the product part of the CPE from the SBOM file to search
through descriptions of unanalyzed CVEs in NVD. This can be beneficial for
getting early notifications about potential new CVEs that have not yet been
analyzed by the NVD and do not have a CPE assigned. In addition to the CPE
product name, all keywords specified in cve-keywords in the related
manifest file, which are also included in the SBOM, are checked. For instance,
the CPE product part for mbedtls is mbed_tls, so this keyword will be
searched when --extended-scan is used. If the mbedtls library manifest file
contains mbed tls and mbedtls in cve-keywords, these will also be
searched. Be aware that using the --extended-scan option may result in false
positive reports that are unrelated to the scanned packages or their versions.
These reports must be thoroughly analyzed and are included in a separate table
titled Packages with Possible Vulnerabilities in the report.
The vulnerability check typically uses the NVD REST API by default, provided by https://nvd.nist.gov.
NVD rate-limits requests to its REST API. Without an API key the limit is 5
requests in a rolling 30 second window; with an API key it is 50 requests in
the same window. esp-idf-sbom reads the key from the NVDAPIKEY environment
variable and, when it is set, sends it in the apikey request header and
shortens the delay between requests accordingly, which speeds up the scan
considerably. A free API key can be requested here; see the NVD
Rate Limits documentation for details.
When the online REST API is used without a key, esp-idf-sbom prints a one-time
hint to standard error suggesting the NVDAPIKEY key or the --local-db
mirror. Set the SBOM_NO_HINT environment variable or pass --no-hint to
silence it.
export NVDAPIKEY=YOUR_API_KEY
esp-idf-sbom check [SBOM file]
An alternative source of information for the vulnerability check can be a local
NVD mirror, available from the esp-nvd-mirror repository. The NVD mirror
may provide a faster and more reliable way to perform vulnerability checks in
case there are availability issues with NVD API endpoints or when a large
number of packages need to be scanned quickly. You can enable the use of the
local NVD mirror with the --local-db option.
esp-idf-sbom check --local-db [SBOM file]
By default, the --local-db option updates the NVD mirror before performing a
vulnerability check. To disable this, use the --no-sync-db option. Be aware
that the initial setup of the NVD mirror may take some time. You can also
update the NVD mirror manually with the sync-db command.
esp-idf-sbom sync-db
esp-idf-sbom check --local-db --no-sync-db [SBOM file]
Excluding CVEs
esp-idf-sbom maintains a global exclusion list in excluded_cves.yaml in this repository. It is keyed by CVE ID, and each value is either:
- a string -- the CVE is unrelated to any Espressif product and is dropped from the report (for example a Linux kernel CVE that merely mentions a library name used by ESP-IDF), or
- a mapping with
cpesandreason-- the CVE does apply but is considered handled for the listed CPEs and version ranges; the scan still lists it, marked as excluded with the given reason.
The global list can be extended at two local levels by placing an
excluded_cves.yaml file in the same format at the appropriate root directory.
In both cases entries are merged into the global list for that scan only, and on
a duplicate CVE ID the local entry wins.
ESP-IDF tree local exclusions
Place excluded_cves.yaml at the root of the ESP-IDF tree to extend the
exclusion list for both manifest check and SBOM generation (create). This
is the right level for ESP-IDF maintainers: the file lives in the IDF tree
itself, so the exclusion and the fix can ride on a release branch together.
This is useful when a CVE cannot be distinguished from an affected release by
version alone. A release branch keeps the version of the last released ESP-IDF
until the next release is cut (for example release/v6.0 still reports 6.0.1
even though 6.0.1 is out), and NVD lists exactly that version as affected. A
version-scoped entry in the global file cannot tell the fixed branch apart from
the genuinely affected release without also hiding the CVE for users still on
that release.
# <ESP-IDF root>/excluded_cves.yaml
CVE-2026-45160:
cpes:
- cpe: cpe:2.3:a:espressif:esp-idf:6.0.1:*:*:*:*:*:*:*
reason: >-
Fixed on release/v6.0. The branch still self-reports 6.0.1 (the version NVD
lists as affected) until 6.0.2 is released.
Project-local exclusions
Place excluded_cves.yaml at the root of your ESP-IDF project (the directory
that contains CMakeLists.txt and whose build/ directory holds
project_description.json) to extend the exclusion list for SBOM generation
only (create command). This is the right level for application developers: the
file stays in the project repository and applies whenever that project's SBOM is
generated, without affecting other projects or manifest check runs.
Use this to suppress CVEs that do not apply to your specific firmware build -- for example because a vulnerable code path is disabled by your sdkconfig, or because your hardware variant is not affected.
# <project root>/excluded_cves.yaml
CVE-2025-12345:
cpes:
- cpe: cpe:2.3:a:example:libfoo:2.3.1:*:*:*:*:*:*:*
reason: >-
The vulnerable feature is disabled in this project's configuration
(CONFIG_LIBFOO_FEATURE_X is not set).
For either local file, prefer the scoped cpes form over the plain-string
form: the scoped form keeps the CVE visible in the report as excluded with a
reason, while the string form drops it from the scan output entirely. Once the
fix ships in a bumped version, NVD no longer matches it and the entry can be
removed.
Usage example
This is an example of basic usage for the blink project, which is part of the ESP-IDF. It's expected that ESP-IDF is installed and set.
$ cd examples/get-started/blink/ # In esp-idf directory go to the blink example
$ idf.py build # Project has to be built first
$ esp-idf-sbom create -o blink.spdx build/project_description.json
$ esp-idf-sbom check blink.spdx
$ esp-idf-sbom create build/project_description.json | esp-idf-sbom check
The resulting blink.spdx sbom file can be found in the blink project directory.
SBOM layout
The SBOM file is created based on application sources, build artefacts, information
provided by the ESP-IDF build system and SBOM manifest files. The resulting SBOM
describes a package for the final project application, the framework
(ESP-IDF itself), the used toolchain, the components used during build, git
submodules and subpackages. The framework package carries the ESP-IDF
version and the CPEs Espressif uses in NVD advisories (the application CPE plus the
generic esp32 hardware and esp32_firmware OS CPEs); the project package
depends on it instead of carrying the ESP-IDF CPE directly. The subpackages
are created based on sbom.yml manifest files found in submodules and subpackages
sub-directories or referenced manifest files or manifest files for virtual packages.
Please see Manifest file.
Each package carries, as available, its name, version, supplier, repository, CPE(s),
PURL, license, copyright and the list of excluded CVEs. Packages are linked together
with dependency relationships rooted at the project package. By default packages for
configuration only components and components not linked into the application are present
in the SBOM, but are not linked as dependencies of the project. In other words
dependencies on such packages are removed. This behaviour can be altered with
--add-config-deps and --add-unused-deps command line options.
Output formats
The same SBOM model is serialized into the format selected with the create --format
option (see Creating SBOM). The check command reads any of them and
detects the format automatically. The model concepts map to each format as follows.
| Concept | SPDX 2.x | SPDX 3.0 JSON-LD | CycloneDX |
|---|---|---|---|
| package | SPDX package | software_Package |
component |
| dependency | DEPENDS_ON relationship |
dependsOn relationship |
dependencies entry |
| name | PackageName |
name |
name |
| version | PackageVersion |
software_packageVersion |
version |
| supplier | PackageSupplier |
suppliedBy (Agent) |
supplier.name |
| originator | PackageOriginator |
originatedBy (Agent) |
publisher |
| description | PackageSummary |
description |
description |
| repository | ExternalRef OTHER repository |
externalRef (vcs) |
externalReferences (vcs) |
| download URL | PackageDownloadLocation |
software_downloadLocation |
externalReferences (distribution) |
| CPE | ExternalRef SECURITY cpe23Type |
cpe23 externalIdentifier |
cpe (+ evidence.identity) |
| PURL | ExternalRef PACKAGE-MANAGER purl |
software_packageUrl |
purl |
| license | PackageLicenseConcluded / Declared |
hasConcludedLicense / hasDeclaredLicense |
licenses |
| copyright | PackageCopyrightText |
software_copyrightText |
copyright |
| checksum | PackageChecksum |
verifiedUsing (Hash) |
hashes |
| excluded CVEs | PackageComment |
security_Vulnerability + VEX |
not_affected VEX vulnerabilities |
| cve-keywords | PackageComment |
comment (YAML) |
properties |
spdx-json-ld emits SPDX 3.0, which has a different, element-based model (JSON-LD is its
only serialization) and validates against the official SPDX 3.0.1 JSON schema.
The concepts above belong to individual packages. The document as a whole carries two
more, set from the document key of the project manifest (see
Manifest file).
| Concept | SPDX 2.x | SPDX 3.0 JSON-LD | CycloneDX |
|---|---|---|---|
| document supplier | not available | not available | metadata.supplier |
| document manufacturer | Creator: |
CreationInfo.createdBy |
metadata.manufacturer |
The two are not symmetric across formats. SPDX has no document level slot for the supplier
of the described product, its nearest equivalent being the root package's own
PackageSupplier, so only the manufacturer is recorded there. In SPDX 3.0 the manufacturer
becomes an Organization agent carrying email and urlScheme external identifiers, and
in SPDX 2.x the contact is folded into the Creator value as name (email).
Manifest file
During SBOM generation the esp-idf-sbom tool is looking for sbom.yml manifest files.
They are used as a source of information for the corresponding package in the SBOM file
as described above.
The manifest file may be present at root of project, component, submodule or
in any of their sub-directories. If sbom.yml is found in a sub-directory a new subpackage
package is created and linked with the parent package. This can be used in cases
where e.g. one component contains multiple libraries and they should be represented
by separate packages.
Example of multiple sbom.yml files usage for the console component.
console
├── argtable3
│ └── sbom.yml
├── linenoise
│ └── sbom.yml
└── sbom.yml
The esp-idf-sbom tool will create main console component package, which will
contain two subpackages for argtable3 and linenoise libraries. Please note that
the manifest file in the console component root directory is not necessary to create
a package, because esp-idf-sbom automatically creates a package for each
component. The sbom.yml files may be placed at any sub-directory depth and
esp-idf-sbom will create proper package hierarchy for them.
The sbom.yml is a simple yaml file, which may contain the following entries.
-
name: Package name that will be used in the package.
-
version: Package version.
-
description: Short package description.
-
repository: Link to git repository.
-
url: Link to package download location.
-
cpe: CPE used for vulnerabilities check against NVD. This can be single CPE value or a list of CPEs.
-
purl: Package URL (PURL) identifying the source of the package (see Output formats). Like
cpe, the value supports the{}placeholder which is substituted with the packageversion, so the PURL template is written once and a version bump only touches theversionfield:name: zlib version: 1.3.2 cpe: cpe:2.3:a:zlib:zlib:{}:*:*:*:*:*:*:* purl: pkg:github/madler/zlib@{}Only a single PURL per package is supported. PURL identifies the source of the artifact (one URL per package), while the multi-value
cpelist already covers the case where the same software is tracked in NVD under multiple vendor names.When
purlis not set explicitly, a PURL is auto-derived from the commit the package was built from, with the package path inside the repository as the PURL subpath:pkg:github/espressif/esp-idf@<sha>#components/heapThe commit comes from the checkout, or for a managed component from the
repository_infothe IDF Component Registry writes intoidf_component.yml. ThegithubandgitlabPURL types define the version as a commit or tag, and a package version is usually neither, so it is not used when a commit is known. If no commit is known, the package version is used withurlpreferred overrepository. This applies to the toolchain, whose version is a release tag.Only
github.comandgitlab.comrepository root URLs are recognised. Other hosts (e.g.https://www.lua.org/) need an explicitpurl. Virtual packages never auto-derive from a commit, because they own no directory and would get the PURL of the component that declares them.The explicit
purlvalue also acts as an override for forks where the auto-derived "where we built from" PURL is not what downstream OSV/GHSA-style scanners would query (e.g. formbedtls, the resolved submodule URL isgithub.com/espressif/mbedtlsbut advisories are indexed against the upstreamgithub.com/Mbed-TLS/mbedtls):sbom-purl = pkg:github/Mbed-TLS/mbedtls@{} -
supplier: Package supplier. Person or organization distributing the package. Should be prefixed with Person: or Organization: as described in SPDX specification.
-
originator: Package originator. If the package comes from another person or organization that has been identified as a supplier. For example if a component is based on 3rd party code with some modifications, the originator is the 3rd party code author, but the supplier is the person or organization distributing the final component. For more detailed information please see the SPDX specification. As for supplier, Person: or Organization: prefix should be used for originator value.
-
hash: SHA of the directory(
git-treeobject) the manifest file describes or HEAD SHA of a submodule. This value is used during the manifest file validation to check if the hash in the manifest file matches the SHA recorded in thegit-tree. Its purpose is to make sure that the information in the manifest file is up-to-date. For example if a submodule or 3rd party library is updated, the version in the manifest file should be probably updated too. The SHA value can be obtained e.g. withgit ls-tree HEAD <path>, where<path>is a package directory, which is described by the manifest file. Please note that a hash value for a directory, not a submodule, cannot be placed in manifest file, which is stored within the same directory, because the directory SHA ingit-treewill change every time the manifest file changes(chicken egg problem). To make the hash variable work, it needs to be placed in a referenced manifest, which is not stored within a directory it describes. For example freertos component can have mainsbom.ymlmanifest file, which refers tosbom_FreeRTOS-Kernel.ymlmanifest describing theFreeRTOS-Kernelpackage in theFreeRTOS-Kerneldirectory.
components/freertos/sbom.yml
manifests:
- path: sbom_FreeRTOS-Kernel.yml
dest: FreeRTOS-Kernel
components/freertos/sbom_FreeRTOS-Kernel.yml
name: 'freertos'
version: '10.4.3'
cpe: cpe:2.3:o:amazon:freertos:{}:*:*:*:*:*:*:*
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
originator: 'Organization: Amazon Web Services'
description: An open-source, real-time operating system (RTOS) with additional features and patches from Espressif.
hash: 4e8101b6f57a0640ae54c6da605c1b532c0f8f89
cve-exclude-list:
- cve: CVE-2021-43997
reason: This vulnerability only affects ARMv7-M and ARMv8-M ports of FreeRTOS and hence does not affect Espressif SoCs which are not based on these architectures.
-
license: License expression explicitly declared by the author.
-
copyright: Copyright explicitly declared by the author. This can be single string or a list of copyrights.
-
cve-exclude-list: List of already evaluated CVEs, which do not apply to this package. This can be used to exclude CVEs from the
esp-idf-sbomchecker report in case the package is not vulnerable to specific CVEs. Each CVE in the exclude list is represented as dictionary with thecveandreasonkeys. Information about excluded CVEs is added to the generated SBOM file, into thePackageCommentSPDX tag or as anot_affectedCycloneDX VEX statement, and later used by the checker.- cve: CVE-ID
- reason : description why this package is not vulnerable to this CVE
version: 0.1.0
description: Blink application example
cve-exclude-list:
- cve: CVE-2023-1234
reason: Description why this package is not vulnerable
- cve-keywords:
When using the
--extended-scanoption to run the checker, look for these keywords in the CVE descriptions. These keywords are also included in the generated SBOM file.
cve-keywords:
- mbedtls
- mbed tls
-
manifests: List of manifests which cannot be added directly into the component or submodule sub-directories to create subpackage. For example the following will create a new package for the
subpackagedirectory with information from thesubpackage.ymlmanifest file. This manifest file is treated as it would be actually stored in thesubpackagedirectoery.- path: path of manifest file relatitve to the sbom.yml
- dest: destination directory for path, again relative to sbom.yml
version: 0.1.0
description: Blink application example
manifests:
- path: subpackage.yml
dest: subpackage
Alternatively, the content of `subpackage.yml` can be directly included as a **manifest** dictionary.
* manifest: a dictionary that holds information about the subpackage manifest
* dest: destination directory for manifest, relative to sbom.yml
version: 0.1.0
description: Blink application example
manifests:
- manifest:
name: 'sub-package'
version: '1.2.3'
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
description: 'Some useful description'
dest: subpackage
- virtpackages: In some situations, it can be beneficial to define a relationship or dependency on a package that isn't physically available during compilation. For example, certain functionality required by an application might be implemented in ROM and used by the application. A case in point is mbedtls, which could reside in the ROM and be utilized by the application depending on configuration settings. In these instances, a virtual package can be useful to represent this dependency.
virtpackages:
- virt_pkg1.yml
- virt_pkg2.yml
-
if: An expression utilizing the configuration variables can conditionally include a package. This condition is disregarded for project and component packages, which are always included. The operators listed below, in order of decreasing precedence, can be used. The order of operations can be adjusted using brackets. If the expression evaluates to true, the package is included. The --disable-conditions option can disable conditions usage.
- !: negation
- <, >, >=, <=: comparison
- =, !=: equal, not equal
- &&: logical and
- ||: logical or
if: 'IDF_TARGET = "esp32"'
if: '(IDF_TARGET_ESP32 || IDF_TARGET = "esp32") && !IDF_TOOLCHAIN_GCC'
if: '1536 <= FREERTOS_ISR_STACKSIZE < 0xffff'
-
document: Information about the generated SBOM document itself, rather than about the package whose directory holds the manifest. This is the only key that does not describe a package. It is read from the project manifest only, and has no effect in any other manifest. It lives in
sbom.ymlfor convenience, so that no separate document metadata file is needed.Two organizations can be described, both optional.
- supplier: the organization supplying the product this SBOM describes,
stating at document level what the project package's
supplierstates about the described product. As there, this is whoever delivers the product to its recipient, which need not be whoever wrote it. When an application is redistributed, for example built by one organization and then shipped by another under its own name, the redistributing organization is the supplier and the original author belongs in the project package'soriginator. This is also the organization a recipient is expected to contact about a vulnerability in the delivered product. - manufacturer: the organization that produced the SBOM document. This is
not the vendor of the
esp-idf-sbomtool, which is recorded separately among the document's tools; it is the organization running the tool.
For an organization building and shipping its own firmware the two are the same. They differ when the document is produced by someone other than the party delivering the product, for example when the original builder generates the SBOM for an application that another organization then redistributes. Each takes the following entries.
- name: prefixed with Person: or Organization:, as for
supplier. - url: link to the organization, for example its home or security page.
- contact: email address for reporting vulnerabilities.
nameis required, together with at least one ofurlorcontact. A name on its own identifies the organization but gives no way to reach it, which is what consumers checking an SBOM for a reachable vulnerability contact are looking for. - supplier: the organization supplying the product this SBOM describes,
stating at document level what the project package's
document:
supplier:
name: 'Organization: Acme Corp'
url: 'https://acme.example'
contact: 'psirt@acme.example'
manufacturer:
name: 'Organization: Acme Corp'
url: 'https://acme.example'
contact: 'psirt@acme.example'
Example of the sbom.yml manifest file for the ESP-IDF blink project.
version: 0.1.0
description: Blink application example
url: https://blink.org/blink-0.1.0.tar.gz # non-existing package download URL example
cpe: cpe:2.3:a:hrbata:blink:{}:*:*:*:*:*:*:* # non-existing CPE example
supplier: 'Person: Frantisek Hrbata (frantisek.hrbata@espressif.com)'
originator: 'Organization: Espressif Systems (Shanghai) CO LTD'
cve-exclude-list:
- cve: CVE-2023-1234
reason: Description why this package is not vulnerable
- cve: CVE-2023-1235
reason: Description why this package is not vulnerable
Information from the sbom.yml manifest file is mapped to the following SPDX tags and
CycloneDX fields.
| manifest | SPDX | CycloneDX |
|---|---|---|
| name | PackageName | name |
| version | PackageVersion | version |
| description | PackageSummary | description |
| repository | ExternalRef OTHER repository | externalReferences (vcs) |
| url | PackageDownloadLocation | externalReferences (distribution) |
| cpe | ExternalRef cpe23Type | cpe (+ evidence.identity) |
| supplier | PackageSupplier | supplier.name |
| originator | PackageOriginator | publisher |
| license | PackageLicenseDeclared | licenses |
| copyright | PackageCopyrightText | copyright |
| cve-exclude-list | PackageComment | not_affected VEX |
| cve-keywords | PackageComment | properties |
The document key is the exception, as it describes the document rather than a package
and is read from the project manifest only.
| manifest | SPDX | CycloneDX |
|---|---|---|
| document.supplier | not available | metadata.supplier |
| document.manufacturer | Creator | metadata.manufacturer |
Even though the sbom.yml file is the primary source of information, the esp-idf-sbom tool
is also looking at other places if it's not present. The idf_component.yml manifest file,
used for components managed by the component manager, may contain sbom dictionary/namespace,
which will be used by esp-idf-sbom if presented. This dictionary may contain the same information
as sbom.yml.
Example of the idf_component.yml manifest file for led_strip managed component.
dependencies:
idf:
version: '>=5.0'
description: Driver for Addressable LED Strip (WS2812, etc)
url: https://github.com/espressif/idf-extra-components/tree/master/led_strip
version: 2.4.1
sbom:
cpe: cpe:2.3:a:hrbata:led_strip:{}:*:*:*:*:*:*:* # non-existing CPE example
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
cve-exclude-list:
- cve: CVE-2023-1234
reason: Description why this package is not vulnerable
- cve: CVE-2023-1235
reason: Description why this package is not vulnerable
If the sbom dictionary is not presented in idf_component.yml or it's missing some information,
the version, description, maintainers and url information from idf_component.yml manifest is used.
Information from the idf_component.yml manifest file is mapped to the following SPDX tags
and CycloneDX fields.
| manifest | SPDX | CycloneDX |
|---|---|---|
| name | PackageName | name |
| version | PackageVersion | version |
| description | PackageSummary | description |
| maintainers | PackageSupplier | supplier.name |
| url | PackageDownloadLocation | externalReferences (distribution) |
Component version may be guessed based on git-describe and Espressif as a default supplier may be guessed based on git repository or package URL. The guessing may be disabled by using the '--no-guess' option.
For git submodules, the .gitmodules configuration file is also checked for additional submodule
information. Submodule configuration may contain variables with the sbom- prefix, which are considered as
SBOM manifest information. All keys used in the sbom.yml manifest file can also be specified in
.gitmodules with the git-config format instead of yaml.
Example of manifest information added for the micro-ecc submodule in .gitmodules.
[submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"]
path = components/bootloader/subproject/components/micro-ecc/micro-ecc
url = ../../kmackay/micro-ecc.git
sbom-version = 1.0
sbom-cpe = cpe:2.3:a:micro-ecc_project:micro-ecc:{}:*:*:*:*:*:*:*
sbom-supplier = Person: Ken MacKay
sbom-url = https://github.com/kmackay/micro-ecc
sbom-description = A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors
sbom-hash = d037ec89546fad14b5c4d5456c2e23a71e554966
sbom-cve-exclude-list = CVE-2023-1234 Description why this package is not vulnerable
sbom-cve-exclude-list = CVE-2023-1235 Description why this package is not vulnerable
Manifest information is gathered in the following order and only missing
values are added. If e.g. version is found in sbom.yml any other
version value found e.g. in .gitmodules is ignored.
- referenced manifest from parent package
sbom.ymlsbomdictionary/namespace inidf_component.yml- sbom information contained in submodule configuration in
.gitmodules idf_component.ymlinformation provided for component manager
Validating manifest files
Manifest files are validated while the SBOM is generated. They can be also validated explicitly
with the esp-idf-sbom manifest validate command.
esp-idf-sbom manifest validate [PATH_TO_VALIDATE...]
PATH_TO_VALIDATE is an optional path to a manifest file(sbom.yml, idf_component.yml or .gitmodules) or
directory, which will be searched for manifest files. If PATH_TO_VALIDATE is not provided, the current
working directory is used.
Usage example:
$ esp-idf-sbom manifest validate ~/work/esp-idf ~/work/idf-extra-components/
$ esp-idf-sbom manifest validate ~/work/esp-idf/.gitmodules ~/work/esp-idf/components/freertos/FreeRTOS-Kernel/sbom.yml
Checking manifest files for vulnerabilities
The esp-idf-sbom tool uses the generated SBOM file to check for possible vulnerabilities.
It also allows to scan for vulnerabilities based on the information presented in manifest
files. This can be used e.g. to scan a whole repository without a need to generate the SBOM file.
esp-idf-sbom manifest check [PATH_TO_CHECK...]
PATH_TO_CHECK is an optional path to a manifest file(sbom.yml, idf_component.yml or .gitmodules) or
directory, which will be searched for manifest files. If PATH_TO_CHECK is not provided, the current
working directory is used.
Usage example:
$ esp-idf-sbom manifest check ~/work/esp-idf ~/work/idf-extra-components/
$ esp-idf-sbom manifest check ~/work/esp-idf/.gitmodules ~/work/esp-idf/components/freertos/FreeRTOS-Kernel/sbom.yml
# Use a local NVD mirror for vulnerability checks.
$ esp-idf-sbom manifest check --local-db ~/work/esp-idf ~/work/idf-extra-components/
Licenses and Copyrights
Adding licenses and copyrights information into the SBOM file has to be explicitly
requested by using the --file-tags option. This requires to scan all files and
may take some time. It also may result in a quite big SBOM file.
All component and submodule files are scanned for the SPDX-License-Identifier,
SPDX-FileCopyrightText and SPDX-FileContributor SPDX file tags. Information from
these tags is used in the generated SBOM file to specify licenses and copyrights for
the packages which represent project, component or submodule. The project's
final license expression is a logical AND of all licenses concluded from components
and submodules used in the final project binary.
The license can be also explicitly declared by the author in the sbom.yml file with the license
variable. This information is used as the declared license of the
given project, component or submodule (see Output formats).
Return Values
- 0: No error, no vulnerability found, manifest file(s) valid.
- 1: Vulnerability found or manifest file not valid.
- 128: Fatal error.
Resources
- DevCon24 presentation - Enhancing IoT Security Generating SBOMs with esp-idf-sbom
Metadata
Release files for esp-idf-sbom 1.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| esp_idf_sbom-1.4.0.tar.gz | 139.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| esp_idf_sbom-1.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 242.4 kB
Release files / esp_idf_sbom-1.4.0.tar.gz
| Download URL | esp_idf_sbom-1.4.0.tar.gz |
|---|---|
| Size | 139.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
578923c1d58f7e5c432780611d055ab163c64229a91a10807bac00bfb608c844
|
|
BLAKE2b-256 checksum How to use checksums |
a96765f0521d95244ed0915589c9f33727d64d817dafeb6b0776599a6a017abb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / esp_idf_sbom-1.4.0-py3-none-any.whl
| Download URL | esp_idf_sbom-1.4.0-py3-none-any.whl |
|---|---|
| Size | 103.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3fa24ff1c14fca159ed85ff32241e50a23f392c606b314cd13f5b5b758f4d45f
|
|
BLAKE2b-256 checksum How to use checksums |
a87afe104bd4a7492b8308be6a543844bb25113729371fe8bce7598d6c5f7496
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency log