Merge SBOMs by feeding several files to a merge tool. A flat merge pools every component into one list. A hierarchical merge keeps each service as its own subtree under a new top level product. Choose flat for inventory questions and hierarchical when you must still say which service holds which component.
Flat or hierarchical
| Question | Flat merge | Hierarchical merge |
|---|---|---|
| Is it one list of components? | Yes | No, nested under each service |
| Can you tell which service uses a package? | Not easily | Yes |
| Needs a name and version for the whole product? | No | Yes |
| Needs each input to name its own subject? | No | Yes, in the metadata component |
| Suited to | Fleet wide search, license sweep | Customer deliverable, per service ownership |
Steps with the CycloneDX tool
- Generate one SBOM per service, in the same format, from the same release.
- Make sure each file names its subject in the metadata component. Hierarchical merge requires this.
- Run the merge.
cyclonedx-cli merge --input-files api.json web.json worker.json --output-file product.json
- For a hierarchical result, add the hierarchical option with a name and version for the product, and optionally a group.
- Validate the merged file before sharing.
The tool also converts and validates, so you can normalize every input first.
What goes wrong
- Inputs from different tools can describe the same component with different identifiers, so a flat merge may show duplicates. Package URLs help here, because they give one reliable name per package.
- A merged file is only as current as its newest input. Stamp it with the release it represents.
- Merging hides gaps. If one service SBOM is thin, the product SBOM looks complete but is not.
When not to merge
If services ship and version independently, a merged SBOM goes stale whenever any one of them deploys. Keep the per service files as the source of truth and build the merged one on demand for a request or audit. A customer who only runs one of your services should get that service's file, not the whole product.
A short example: a product has three services, api, web and worker. Each pipeline publishes its own file on release. A nightly job merges the latest of each into one product file for the security team's search, using the flat form. When a customer asks for the product SBOM, a second job builds the hierarchical form for the exact release they run. Same inputs, two outputs, each shaped for its reader.
Quick check
Is a merged SBOM the same as an SBOM of the product?
Only if the services together are the product. Anything outside them, such as a base image or a shared library you ship separately, must be added.
Do I need a version for a flat merge?
No. The name and version are required only for the hierarchical form.
Safeguard's SBOM and dependency scanning organizes components by project and product, and a free scan is available at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.