SBOM — Software Bill of Materials
Platform-wide supply chain transparency tooling: every service generates a machine-readable inventory of its dependencies for security auditing, license compliance, and regulatory reporting.
1. Overview
A Software Bill of Materials (SBOM) is a complete, machine-readable inventory of every open-source and third-party component inside a piece of software — the equivalent of an ingredients list on a food label.
The Equinox Platform implements SBOM generation as a per-service npm script (npm run sbom:generate). The script uses the industry-standard CycloneDX format (spec version 1.5), scans the service’s node_modules and package.json, and writes an enriched JSON artifact to a local sbom/ directory. Two variants of the script exist:
- Basic variant — used by
eq-auth-service(and similar). Generates a CycloneDX document and appends a small set of build/runtime metadata properties. - Enhanced variant — used by
eq-inventory-service(and similar). Adds a fullsbomConfigdeclaration block that maps every backend framework, database driver, cloud SDK, custom library, DevOps component, test framework, third-party integration, and microservice endpoint. It also auto-detects AWS CDK resources from thecdk/directory and merges security/AI/MCP status metadata.
The generated file is consumed by security scanners, audit tools (e.g. Snyk, OWASP Dependency-Check), license-compliance pipelines, and any procurement/regulatory process that requires a full supply chain manifest.
Business Value
| Capability | Outcome |
|---|---|
| Complete dependency inventory | Every npm package (direct + transitive) listed with version — no hidden dependencies |
| License compliance | Detect GPL/AGPL dependencies before they reach production |
| Vulnerability alerting | Feed to Snyk / OWASP Dependency-Check / npm audit to catch CVEs in real time |
| Regulatory compliance | Satisfies US Executive Order 14028, EU Cyber Resilience Act SBOM mandates for enterprise/government buyers |
| Build provenance | Each artifact is stamped with git commit SHA, branch, timestamp, and Node.js version |
| Supply chain transparency | Procurement teams can verify exactly what software runs in production |
| Multi-layer tracking | Not just npm — CDK infrastructure, test frameworks, CI/CD pipelines, and cloud services also catalogued |
Who Uses It
| Persona | Interaction |
|---|---|
| Platform / DevOps engineer | Runs npm run sbom:generate locally or as part of a release pipeline to produce the artifact |
| Security team | Feeds the sbom/ JSON into Snyk, OWASP Dependency-Check, or an internal SBOM registry to scan for CVEs and license violations |
| Compliance / audit team | Attaches the SBOM artifact to release records for regulatory evidence (EO 14028, CRA, SOC 2) |
| Procurement / enterprise buyer | Reviews SBOM to verify third-party components before approving software procurement |
| PIM service CI | The only service with an additional npm run sbom:validate step — validates the generated artifact against schema |
Related Resources
- CycloneDX specification: https://cyclonedx.org/specification/overview/
- cdxgen tool: https://github.com/CycloneDX/cdxgen
- SBOM output location:
<service-root>/sbom/ - Versioned filename:
<pkg-name>-<version>-cyclonedx.json - Always-current copy:
<pkg-name>-latest-cyclonedx.json
2. Core Features
| # | Feature | Description | Applies to |
|---|---|---|---|
| 1 | CycloneDX 1.5 generation | Produces a fully spec-compliant CycloneDX JSON SBOM via @cyclonedx/cdxgen scanning all npm dependencies |
All services |
| 2 | Build provenance metadata | Stamps every SBOM with git commit SHA, branch, ISO timestamp, Node.js version, service type, and service domain | All services |
| 3 | Versioned + latest output | Writes two files: <name>-<version>-cyclonedx.json (immutable archive) and <name>-latest-cyclonedx.json (always-current pointer) |
All services |
| 4 | Structured component declaration | Enhanced variant maps 10 categories of components explicitly in sbomConfig: backend, devops, QE, integrations, microservices, admin, security, AI, MCP, detected resources |
eq-inventory-service and enhanced variants |
| 5 | CDK resource auto-detection | Scans ./cdk/*.ts / *.js files and detects Lambda functions, API Gateway, RDS, and EventBridge declarations automatically |
Enhanced variant |
| 6 | API endpoint tracking | Extracts and records all documented API endpoint paths into SBOM metadata | Enhanced variant |
| 7 | Security posture metadata | Records vulnerability scanning tools (npm audit, OWASP, Snyk), static analysis tool (SonarQube), and security header config (Helmet/CSP/CORS) | Enhanced variant |
| 8 | AI / MCP status tracking | Documents whether AI integrations and MCP server integrations are implemented or planned | Enhanced variant |
| 9 | SBOM validation | eq-pim-service additionally runs npm run sbom:validate to verify the generated artifact against the CycloneDX schema |
eq-pim-service only |
| 10 | In-memory / offline safe | No network calls during generation — all data comes from local node_modules, package.json, and the cdk/ directory |
All services |
3. How It Works — Generation Pipeline
npm run sbom:generate
│
▼
Read package.json
(name, version, description, author)
│
▼
Read git metadata
(git rev-parse --short HEAD → commit)
(git rev-parse --abbrev-ref HEAD → branch)
│
▼
Create ./sbom/ directory (recursive, idempotent)
│
▼
Run @cyclonedx/cdxgen
(-t js --spec-version 1.5
--author "Equinox Platform Team"
--supplier "Equinox"
-o ./sbom/<name>-<version>-cyclonedx.json)
│
▼
Parse generated JSON
│
├── [Basic variant stops here — skip to Metadata Enrichment]
│
├── [Enhanced variant — auto-detect phase]
│ detectCDKResources()
│ └── scan ./cdk/*.ts / *.js for:
│ lambda.Function → { type: "lambda" }
│ apigateway → { type: "api-gateway" }
│ rds → { type: "rds" }
│ eventbridge → { type: "eventbridge" }
│ detectAPIEndpoints()
│ └── read sbomConfig.microservices.services[].endpoints
│
├── [Enhanced variant — component injection phase]
│ Append to sbomData.components[]:
│ 1. Backend frameworks (type: library, group: Backend-Components, layer: Application Framework)
│ 2. Database drivers (type: library, layer: Data Access)
│ 3. Cloud SDKs (type: library, layer: Cloud SDK)
│ 4. Custom libraries (type: library, layer: custom)
│ 5. Compute platform (type: platform, layer: Compute)
│ 6. Infrastructure (type: application, layer: Infrastructure)
│ 7. CI/CD pipelines (type: application, layer: CI/CD)
│ 8. Containers (type: container, layer: Containerization)
│ 9. E2E tests (type: library, scope: optional, layer: E2E Testing)
│ 10. Unit tests (type: library, scope: optional, layer: Unit Testing)
│ 11. API test libs (type: library, scope: optional, layer: API Testing)
│ 12. Reporting libs (type: library, scope: optional, layer: Test Reporting)
│ 13. Auth integrations (type: application, supplier: vendor)
│ 14. DB integrations (type: application)
│ 15. Event streaming (type: application)
│ 16. Caching (type: application, status: optional)
│ 17. Monitoring (type: application)
│ 18. Microservices (type: application, endpoints, dataClassification, trustBoundary)
│ 19. Admin consoles (type: application, access-level, security)
│
▼
Metadata Enrichment (sbomData.metadata.properties[])
─────────────────────────────────────────────────────
equinox:build:timestamp → ISO 8601 datetime
equinox:build:commit → short git SHA (or "unknown")
equinox:build:branch → branch name (or "unknown")
equinox:runtime:nodejs → process.version (e.g. v22.x)
equinox:service:type → e.g. "fastify-lambda", "inventory-service"
equinox:service:domain → e.g. "inventory-management"
[Enhanced only:]
orchestration:platform → "AWS Lambda with API Gateway"
orchestration:eventBus → "AWS EventBridge for async event processing"
orchestration:cronJobs → e.g. "EventBridge Rules for replenishment scheduling"
security:vulnerability-scanning:tools → ["npm audit","OWASP","Snyk"]
security:vulnerability-scanning:status → "Manual - integrate automated scanning"
security:static-analysis:tool → "SonarQube"
security:headers:helmet → "Enabled with CSP, HSTS, X-Frame-Options"
security:headers:cors → "Strict origin whitelist with credentials disabled"
ai:status → "NOT_IMPLEMENTED"
ai:planned → JSON array of planned AI features
mcp:status → "NOT_IMPLEMENTED"
mcp:planned → JSON array of planned MCP tools
detected:cdk-resources → JSON array of CDK-detected AWS resources
detected:api-endpoints → JSON array of API path strings
│
▼
Write versioned file: ./sbom/<name>-<version>-cyclonedx.json
Write latest copy: ./sbom/<name>-latest-cyclonedx.json
│
▼
Console summary printed
(version, commit, branch, Node.js, component counts)
4. SBOM Output Structure
The generated JSON is a valid CycloneDX 1.5 BOM document. Top-level fields:
| Field | Type | Description |
|---|---|---|
bomFormat |
string | Always "CycloneDX" |
specVersion |
string | Always "1.5" |
serialNumber |
string | UUID URN, e.g. urn:uuid:… — unique per generation run |
version |
integer | BOM document version (starts at 1) |
metadata |
object | Service identity, author, timestamp, and all enriched properties |
components |
array | Full dependency tree + injected component entries |
dependencies |
array | Dependency graph edges (package → depends-on list) |
metadata object
| Sub-field | Source | Description |
|---|---|---|
timestamp |
cdxgen | ISO 8601 generation time |
tools[] |
cdxgen | [{ name: "cdxgen", version: "11.7.0" }] |
component |
cdxgen + enrichment | { name, version, description, author } from package.json |
authors[] |
CLI flag | [{ name: "Equinox Platform Team" }] |
supplier |
CLI flag | { name: "Equinox" } |
properties[] |
enrichment script | All equinox:*, orchestration:*, security:*, ai:*, mcp:*, detected:* key-value pairs |
Component entry shape (injected components)
{
"type": "library | platform | application | container",
"bom-ref": "backend:@fastify/fastify",
"group": "Backend-Components",
"name": "Fastify Web Framework",
"version": "detected",
"description": "High-performance web framework for Node.js",
"scope": "required | optional",
"supplier": { "name": "AWS" },
"externalReferences": [{ "type": "website", "url": "https://…" }],
"properties": [
{ "name": "category", "value": "Backend Components & Libraries" },
{ "name": "layer", "value": "Application Framework" },
{ "name": "custom", "value": "true" }
]
}
5. Configuration — sbomConfig Block (Enhanced Variant)
The enhanced generate-sbom.js contains a single sbomConfig constant that acts as the declarative manifest for all non-npm components. Edit this block per service to reflect the service’s actual technology footprint.
sbomConfig sections
| Section | Key | CycloneDX type | What to declare here |
|---|---|---|---|
| Backend frameworks | backend.frameworks[] |
library |
Web framework (Fastify), ORM, etc. |
| Backend databases | backend.databases[] |
library |
DB driver (mysql2, mongoose) |
| Backend cloud SDKs | backend.cloudSDKs[] |
library |
AWS SDK packages used |
| Custom libraries | backend.customLibraries[] |
library |
@equinox/* internal npm packages |
| Compute platform | devops.compute[] |
platform |
AWS Lambda, runtime version |
| Infrastructure | devops.infrastructure[] |
application |
AWS CDK, API Gateway, location |
| CI/CD | devops.cicd[] |
application |
GitHub Actions workflow path |
| Containers | devops.containers[] |
container |
Docker / container runtime |
| E2E testing | qe.e2eTesting[] |
library |
Playwright, location |
| Unit testing | qe.unitTesting[] |
library |
Jest, location |
| API testing | qe.apiTesting[] |
library |
@equinox/eqx-api-automation-core |
| Reporting | qe.reporting[] |
library |
Allure, reporting tools |
| Auth integrations | integrations.authentication[] |
application |
Amazon Cognito, OIDC providers |
| Database integrations | integrations.databases[] |
application |
RDS MySQL, DynamoDB, MongoDB Atlas |
| Event streaming | integrations.eventStreaming[] |
application |
Amazon EventBridge |
| Caching | integrations.caching[] |
application |
Redis (mark status: "optional") |
| Monitoring | integrations.monitoring[] |
application |
AWS X-Ray, CloudWatch |
| Microservices | microservices.services[] |
application |
API name, endpoints[], dataClassification, trustBoundary |
| Orchestration | microservices.orchestration |
metadata | Platform, event bus, cron jobs (written to metadata.properties) |
| Admin consoles | admin.consoles[] |
application |
Swagger UI endpoint, access level |
| Security | security |
metadata | Scanning tools, static analysis, HTTP security headers |
| AI | ai |
metadata | Status (NOT_IMPLEMENTED / ACTIVE) + planned features |
| MCP | mcp |
metadata | Status + planned MCP tools |
bom-ref naming convention
Each injected component gets a bom-ref that is globally unique within the document:
| Prefix | Example |
|---|---|
backend: |
backend:@fastify/fastify, backend:mysql2 |
devops: |
devops:aws-lambda, devops:aws-cdk-infrastructure |
qe: |
qe:@playwright/test, qe:jest |
integration: |
integration:amazon-cognito, integration:redis-cache |
microservice: |
microservice:inventory-management-api |
admin: |
admin:swagger-ui-admin-console |
6. Running SBOM Generation
When to run
| Trigger | Recommended action |
|---|---|
| Pre-release / release cut | Always run npm run sbom:generate and archive the versioned file |
| Major dependency upgrade | Run after npm install to capture the updated tree |
| Security incident | Run immediately to get a current snapshot for forensic analysis |
| Onboarding a new service | Add the script and @cyclonedx/cdxgen devDependency on day one |
| Compliance audit | Provide the sbom/ directory or the latest JSON artifact |
How to run (per service)
# Standard services (generate-sbom.js at root)
cd eq-auth-service # or eq-cart-service, eq-oms-service, etc.
npm run sbom:generate
# Inventory service (script in tools/scripts/)
cd eq-inventory-service
npm run sbom:generate
# PIM service — also validate after generating
cd eq-pim-service
npm run sbom:generate
npm run sbom:validate
What you see in the console
Generating SBOM for eq-authservices v9.0.0...
Git: main@a1b2c3d
✓ Generated: eq-authservices-9.0.0-cyclonedx.json
✓ Updated: eq-authservices-latest-cyclonedx.json
SBOM Location: /path/to/sbom/eq-authservices-9.0.0-cyclonedx.json
Metadata:
- Version: 9.0.0
- Commit: a1b2c3d
- Branch: main
- Node.js: v22.x.x
Enhanced variant additionally prints:
Components Tracked:
- Backend: 1 frameworks, 1 databases
- DevOps: 1 compute, 2 infrastructure
- QE: 2 test frameworks
- Integrations: 5 services
- Microservices: 1 services
7. Services Coverage
| Service | Script location | npm script | Validate step | Version |
|---|---|---|---|---|
eq-auth-service |
generate-sbom.js |
sbom:generate |
No | 9.0.0 |
eq-cart-service |
generate-sbom.js |
sbom:generate |
No | 9.0.1 |
eq-oms-service |
generate-sbom.js |
sbom:generate |
No | 9.0.1 |
eq-pim-service |
generate-sbom.js |
sbom:generate |
Yes (sbom:validate) |
9.0.2 |
eq-foundation-service |
generate-sbom.js |
sbom:generate |
No | 9.0.2 |
eq-marketplace-service |
generate-sbom.js |
sbom:generate |
No | 1.0.0 |
eq-subscription-service |
generate-sbom.js |
sbom:generate |
No | 1.0.0 |
eq-account-service |
generate-sbom.js |
sbom:generate |
No | 9.0.0 |
eq-user-service |
generate-sbom.js |
sbom:generate |
No | 9.0.1 |
eq-inventory-service |
tools/scripts/generate-sbom.js |
sbom:generate |
No | 9.0.1 |
eq-promotion-service |
— | Not configured | — | 9.0.0 |
Note:
eq-promotion-servicedoes not have an SBOM script. It should havegenerate-sbom.jsadded and@cyclonedx/cdxgenadded as a devDependency.
8. Output Files
<service-root>/
└── sbom/
├── <pkg-name>-<version>-cyclonedx.json ← versioned, immutable archive
└── <pkg-name>-latest-cyclonedx.json ← always-current copy (overwritten on each run)
Example (inventory service):
eq-inventory-service/
└── sbom/
├── eq-inventoryservices-9.0.1-cyclonedx.json
└── eq-inventoryservices-latest-cyclonedx.json
The versioned file is suitable for artifact storage (S3, GitHub Releases, Nexus). The latest file is convenient for tooling that always needs the current state without knowing the version.
9. Tool & Dependency Details
@cyclonedx/cdxgen
| Property | Value |
|---|---|
| Package | @cyclonedx/cdxgen |
| Version pinned | 11.7.0 |
| Declared in | devDependencies (not shipped to production) |
| CLI flags used | -t js (JavaScript project), --spec-version 1.5, --author "Equinox Platform Team", --supplier "Equinox", -o <outputPath> |
| What it scans | package.json, package-lock.json / node_modules |
| Output format | CycloneDX JSON (also supports XML, but not used here) |
cdxgen invocation (exact command)
npx @cyclonedx/cdxgen \
-t js \
--spec-version 1.5 \
--author "Equinox Platform Team" \
--supplier "Equinox" \
-o "./sbom/<pkg-name>-<version>-cyclonedx.json"
10. Auto-Detection Logic (Enhanced Variant)
CDK Resource Detection — detectCDKResources()
Scans every .ts and .js file in ./cdk/ using string-pattern matching:
| String found in file | Detected resource type |
|---|---|
lambda.Function |
{ type: "lambda", file: "<filename>" } |
apigateway |
{ type: "api-gateway", file: "<filename>" } |
rds |
{ type: "rds", file: "<filename>" } |
eventbridge |
{ type: "eventbridge", file: "<filename>" } |
Results are pushed into sbomData.metadata.properties as detected:cdk-resources (JSON array).
If ./cdk/ does not exist, the function returns an empty array silently.
API Endpoint Detection — detectAPIEndpoints()
Reads sbomConfig.microservices.services[].endpoints[] and deduplicates the list. Results pushed to detected:api-endpoints in metadata properties.
11. Metadata Properties Reference
All custom properties follow the equinox: namespace convention and are stored in sbomData.metadata.properties[] as { name, value } pairs.
| Property name | Example value | Set by |
|---|---|---|
equinox:build:timestamp |
2026-08-11T10:30:00.000Z |
Both variants |
equinox:build:commit |
a1b2c3d (or "unknown") |
Both variants |
equinox:build:branch |
main (or "unknown") |
Both variants |
equinox:runtime:nodejs |
v22.14.0 |
Both variants |
equinox:service:type |
fastify-lambda / inventory-service |
Both variants |
equinox:service:domain |
inventory-management |
Enhanced variant |
orchestration:platform |
AWS Lambda with API Gateway |
Enhanced variant |
orchestration:eventBus |
AWS EventBridge for async event processing |
Enhanced variant |
orchestration:cronJobs |
EventBridge Rules for replenishment scheduling |
Enhanced variant |
security:vulnerability-scanning:tools |
["npm audit","OWASP Dependency-Check","Snyk"] |
Enhanced variant |
security:vulnerability-scanning:status |
Manual - integrate automated scanning |
Enhanced variant |
security:static-analysis:tool |
SonarQube |
Enhanced variant |
security:static-analysis:status |
Available |
Enhanced variant |
security:headers:helmet |
Enabled with CSP, HSTS, X-Frame-Options |
Enhanced variant |
security:headers:cors |
Strict origin whitelist with credentials disabled |
Enhanced variant |
ai:status |
NOT_IMPLEMENTED |
Enhanced variant |
ai:planned |
["Demand forecasting","Anomaly detection"] |
Enhanced variant |
mcp:status |
NOT_IMPLEMENTED |
Enhanced variant |
mcp:planned |
["Inventory assistant context management"] |
Enhanced variant |
admin:status |
Swagger UI available in dev/staging - Disabled in production |
Enhanced variant |
detected:cdk-resources |
[{"type":"lambda","file":"stack.ts"}] |
Enhanced variant (auto) |
detected:api-endpoints |
["/api/v1/locations","/api/v1/skus"] |
Enhanced variant (auto) |
12. Environment Variables / Prerequisites
The SBOM script itself reads no environment variables. It relies on the following being present:
| Prerequisite | Required | Behaviour if missing |
|---|---|---|
node_modules/ installed |
Yes | cdxgen has no packages to scan; output will be minimal |
package.json at service root |
Yes | Script crashes — pkg.name / pkg.version unavailable |
git CLI on PATH |
No | gitCommit and gitBranch default to "unknown" — generation continues |
./cdk/ directory |
No | CDK detection returns empty array silently (enhanced variant only) |
Write permission to ./sbom/ |
Yes | fs.mkdirSync fails; generation aborts |
@cyclonedx/cdxgen devDependency |
Yes | npx will download it on first run if not cached |
Node.js version
The script uses process.version — whichever Node.js is active on PATH. The Equinox platform targets Node.js 22.x (nodejs22.x Lambda runtime).
13. FAQs
generate-sbom.js?eq-auth-service) calls cdxgen and appends 5 metadata properties (timestamp, commit, branch, Node.js version, service type). The enhanced variant (e.g. eq-inventory-service) adds a full sbomConfig declarative block covering 10 categories of components, CDK auto-detection, API endpoint tracking, and security/AI/MCP status — making the SBOM a comprehensive architecture artifact, not just a dependency list.sbom/ directory at the service root. Two files are written per run: a versioned immutable archive (<name>-<version>-cyclonedx.json) and an always-current latest copy (<name>-latest-cyclonedx.json).npm run sbom:generate). It should be integrated into the release pipeline (e.g. GitHub Actions) so every release build produces and archives an SBOM artifact. This is flagged as a manual step in the security config ("status": "Manual - integrate automated scanning").eq-promotion-service not have an SBOM script?generate-sbom.js (copy from another service and update sbomConfig), add "sbom:generate": "node generate-sbom.js" to package.json scripts, and add @cyclonedx/cdxgen to devDependencies.node_modules and package.json. No network calls are made during generation. All output is written to the local sbom/ directory.gitCommit sometimes "unknown"?.git, or a cloud build that doesn’t clone git history), git rev-parse fails. The script catches the error and defaults to "unknown" — generation still completes successfully.@cyclonedx/cdxgen -t js do exactly?package.json and package-lock.json, enumerates all direct and transitive dependencies from node_modules, and emits a CycloneDX BOM document with each package as a component entry (including purl, version, licenses, and hashes where available).npm run sbom:validate work in eq-pim-service?validate-sbom.js script that reads the generated JSON and checks it against the CycloneDX 1.5 JSON schema. This catches structural errors (missing required fields, wrong types) before the artifact is archived or submitted.sbomConfig block in the enhanced variant is for. Add entries to backend.customLibraries, integrations, or any other section. They will be injected as explicit components[] entries in the output document.npx @cyclonedx/cyclonedx-npm --validate) or the CycloneDX online validator at https://cyclonedx.org/tool-center/. For in-repo validation, follow the pattern in eq-pim-service‘s validate-sbom.js.14. Glossary
| Term | Meaning |
|---|---|
| SBOM | Software Bill of Materials — a machine-readable list of all software components and their dependencies |
| CycloneDX | An OWASP-backed open standard for SBOMs; supported format is JSON spec version 1.5 |
| BOM | Bill of Materials — the document itself (the CycloneDX file) |
bom-ref |
A string identifier that uniquely addresses a component within one CycloneDX document |
cdxgen |
The CLI tool (@cyclonedx/cdxgen) that auto-generates a CycloneDX BOM by scanning npm packages |
| Component | A single entry in the BOM components[] array — may be an npm library, cloud platform, container, or application |
| Metadata properties | Free-form { name, value } pairs in bom.metadata.properties[] used for Equinox-specific enrichment |
sbomConfig |
The declarative configuration block in the enhanced generate-sbom.js that defines non-npm components |
| Basic variant | The simpler generate-sbom.js (e.g. eq-auth-service) that only adds 5 metadata properties after cdxgen runs |
| Enhanced variant | The full generate-sbom.js (e.g. eq-inventory-service) that adds structured component declarations across 10 categories |
| Build provenance | The set of facts (git commit, branch, timestamp, Node.js version) stamped on every SBOM to prove when and from what source it was built |
purl |
Package URL — a standard identifier for an npm package, e.g. pkg:npm/%40fastify%2Ffastify@4.x.x |
| Transitive dependency | A package that your code does not require directly, but is required by one of your direct dependencies |
| License compliance | Verifying that none of the dependencies use licenses (e.g. GPL-3.0) that are incompatible with your software’s distribution model |
| CVE | Common Vulnerabilities and Exposures — a public record of a known security vulnerability in a software component |
| Supply chain | The full set of upstream software (dependencies, tools, build systems) that contributes to your shipped binary |
| CRA | EU Cyber Resilience Act — European regulation requiring SBOM disclosure for connected software products |
| EO 14028 | US Executive Order on Improving the Nation’s Cybersecurity (2021) — mandates SBOM for software sold to the US government |
Revision History
2026-08-12 | JP – Created the page and added the content.