Skip to content

CycloneDX BOM Reference

You can’t secure what you haven’t inventoried. Firmis generates Agent Bills of Materials in CycloneDX 1.7 format — the same standard used for software supply chain compliance under SOC 2, the EU AI Act, and Executive Order 14028. This page is the output format field reference. For the concept and motivation, see Agent BOM.

CycloneDX is an OWASP-sponsored open standard for Software Bill of Materials (SBOM) interchange. Version 1.7 added first-class support for machine learning components (machine-learning-model type), which Firmis uses to record AI model references found in agent configurations.

CycloneDX BOMs are widely accepted by:

ToolUse case
OWASP Dependency-TrackContinuous vulnerability tracking against component inventory
GrypeVulnerability matching against BOM components
GitHub Dependency GraphImport as SBOM to populate the dependency graph
FOSSALicense compliance analysis
Anchore EnterprisePolicy-based security gates on component inventory

Terminal
# Generate BOM for current directory (stdout)
npx firmis bom
# Save BOM to file
npx firmis bom --output agent-bom.json
# BOM for a specific platform only
npx firmis bom --platform mcp --output mcp-bom.json
# As part of the full CI pipeline
npx firmis ci --fail-on high
# Produces agent-bom.json alongside results.sarif

A Firmis Agent BOM is a valid CycloneDX 1.7 JSON document with four top-level fields:

FieldTypeDescription
bomFormatstringAlways "CycloneDX"
specVersionstringAlways "1.7"
versionnumberBOM document version, starts at 1
metadataobjectScan metadata (timestamp, tool info, project root)
componentsarrayAI agent components, dependencies, and models
dependenciesarrayDependency relationships between components

Records when the BOM was generated, which tool generated it, and what project was inventoried.

FieldTypeDescription
metadata.timestampstring (ISO 8601)UTC timestamp of BOM generation
metadata.toolsarrayTool entries: [{ "name": "firmis", "version": "1.3.0" }]
metadata.componentobjectThe root project component being inventoried
metadata.component.typestring"application" for the root project
metadata.component.namestringDirectory name of the scanned project
metadata.component.versionstringVersion from package.json if present

Each AI agent component discovered during the scan is listed as a CycloneDX component. Firmis produces three types of component entries:

FieldTypeDescription
typestring"library" for tools and plugins, "service" for MCP servers
namestringComponent name from manifest or directory name
versionstringVersion from package.json, skill.json, or pyproject.toml
descriptionstringShort description from the manifest, if available
purlstringPackage URL (e.g., pkg:npm/my-tool@0.2.1) if published to a registry
hashesarraySHA-256 hash of the component directory for integrity verification
propertiesarrayFirmis-specific properties: platform, componentType, filesScanned

Dependency components (npm / pip packages)

Section titled “Dependency components (npm / pip packages)”

Dependencies resolved from package.json, requirements.txt, and pyproject.toml are listed as separate components with type "library".

FieldTypeDescription
typestring"library"
namestringPackage name (e.g., axios)
versionstringResolved version (e.g., 1.6.0)
purlstringpkg:npm/axios@1.6.0 or pkg:pypi/requests@2.31.0

When a model reference is detected in a configuration file (e.g., "model": "claude-3-5-sonnet-20241022"), it is recorded as a machine-learning-model component.

FieldTypeDescription
typestring"machine-learning-model"
namestringModel identifier as it appears in the config
descriptionstring"AI model referenced in agent configuration"

Maps component references to their resolved dependencies.

dependencies structure
{
"dependencies": [
{
"ref": "my-search-tool",
"dependsOn": ["axios@1.6.0", "dotenv@16.0.0"]
}
]
}

ref is the component’s name. dependsOn lists the names of components that this component declares as dependencies.


agent-bom.json
{
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"version": 1,
"metadata": {
"timestamp": "2026-03-05T10:00:00.000Z",
"tools": [
{
"name": "firmis",
"version": "1.3.0",
"vendor": "Firmis Labs"
}
],
"component": {
"type": "application",
"name": "my-agent-project",
"version": "1.0.0"
}
},
"components": [
{
"type": "service",
"name": "web-search-mcp",
"version": "0.3.1",
"description": "Web search MCP server for Claude",
"purl": "pkg:npm/web-search-mcp@0.3.1",
"hashes": [
{
"alg": "SHA-256",
"content": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
],
"properties": [
{ "name": "firmis:platform", "value": "mcp" },
{ "name": "firmis:componentType", "value": "server" },
{ "name": "firmis:filesScanned", "value": "12" }
]
},
{
"type": "library",
"name": "my-search-skill",
"version": "1.0.0",
"description": "Claude skill for web search",
"hashes": [
{
"alg": "SHA-256",
"content": "b94d27b9934d3e08a52e52d7da7dabfac484efe04bcd9e5bcd832d9cd4f19f6a"
}
],
"properties": [
{ "name": "firmis:platform", "value": "claude" },
{ "name": "firmis:componentType", "value": "skill" },
{ "name": "firmis:filesScanned", "value": "5" }
]
},
{
"type": "machine-learning-model",
"name": "claude-3-5-sonnet-20241022",
"description": "AI model referenced in agent configuration"
},
{
"type": "library",
"name": "axios",
"version": "1.6.0",
"purl": "pkg:npm/axios@1.6.0"
},
{
"type": "library",
"name": "dotenv",
"version": "16.4.5",
"purl": "pkg:npm/dotenv@16.4.5"
}
],
"dependencies": [
{
"ref": "web-search-mcp",
"dependsOn": ["axios@1.6.0", "dotenv@16.4.5"]
},
{
"ref": "my-search-skill",
"dependsOn": []
}
]
}

Firmis adds custom properties to each component using the firmis: namespace. These are valid CycloneDX custom properties and are ignored by tools that do not recognize them.

PropertyDescription
firmis:platformThe platform this component belongs to (e.g., mcp, claude)
firmis:componentTypeFirmis component type: skill, server, plugin, extension, agent
firmis:filesScannedNumber of files scanned in this component

Upload the BOM via the Dependency-Track API or web UI. Dependency-Track continuously checks your component list against the NVD, GitHub Advisory Database, and OSV — alerting you when a new vulnerability affects a component in your inventory.

Terminal — upload via curl
curl -X "PUT" "https://your-dtrack-instance/api/v1/bom" \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: multipart/form-data" \
-F "projectName=my-agent-project" \
-F "projectVersion=1.0.0" \
-F "autoCreate=true" \
-F "bom=@agent-bom.json"

Grype accepts CycloneDX BOMs directly for vulnerability scanning:

Terminal
grype sbom:./agent-bom.json

Upload using the GitHub Dependency Submission API to populate the Dependency Graph with your agent’s component inventory:

Terminal
gh api --method POST /repos/:owner/:repo/dependency-graph/snapshots \
--input agent-bom.json