Software Bills of Delivery: Beyond SBOMs with Component Models
Traditional Software Bills of Materials (SBOMs) have served as the foundation for software supply chain transparency, but they’re showing their limitations in today’s complex, distributed environments. While SBOMs catalog components and dependencies, they fall short of tracking the complete delivery lifecycle across cloud-native architectures. Enter Software Bills of Delivery and component models—a more comprehensive approach that tracks not just what’s in your software, but how it moves through your entire delivery pipeline.
The SBOM Foundation and Its Limits
A Software Bill of Materials is a formal record of all software component parts and software dependencies used in application development and delivery. The National Telecommunications and Information Administration (NTIA) has established baseline requirements for SBOM creation and delivery, making them increasingly mandatory for government contracts and enterprise software.
SBOMs excel at providing a snapshot of components at build time. They answer critical questions like “What open source libraries are we using?” and “Do we have any known vulnerabilities?” But they struggle with the dynamic nature of modern software delivery:
- Static snapshots vs. dynamic environments: SBOMs capture a point-in-time view, but container images, serverless functions, and microservices change constantly
- Limited artifact tracking: They focus on source dependencies but miss runtime artifacts, configuration files, and deployment metadata
- Deployment context gaps: SBOMs don’t track where components are deployed, how they’re configured, or their runtime relationships
These limitations become critical when you’re managing hundreds of microservices across multiple clusters, each with their own dependency chains and deployment patterns.
Component Models: The Next Evolution
Component models extend beyond traditional SBOMs by treating software artifacts as first-class entities with rich metadata throughout their lifecycle. The Open Component Model (OCM) offers a practical solution for the delivery of software artifacts, providing a standardized way to describe, package, and transport software components with their complete context.
Unlike SBOMs, component models track:
- Artifact provenance: Complete build and deployment history
- Runtime dependencies: Not just compile-time dependencies, but actual runtime relationships
- Configuration metadata: Environment-specific settings and their sources
- Delivery pipelines: How components move through CI/CD systems
- Deployment topology: Where components run and how they communicate
This comprehensive tracking enables what we call “Software Bills of Delivery”—living documents that evolve with your software as it moves through environments.
Software Bills of Delivery in Practice
A Software Bill of Delivery goes beyond listing components to track the complete delivery journey. Here’s what this looks like in a real cloud-native environment:
With OCM, a component constructor file serves as the bill of delivery. It captures not just what artifacts exist, but where they come from and how to access them. The following example is for illustration — refer to the OCM component constructor reference for the authoritative schema:
# component-constructor.yaml — illustrative example, see ocm.software/docs for full schema
components:
- name: github.com/company/user-service
version: 2.1.3
provider:
name: company.com
labels:
- name: build.commit
value: abc123def456
- name: build.timestamp
value: "2024-01-15T10:30:00Z"
- name: build.pipeline
value: github-actions
resources:
- name: container-image
type: ociImage
version: 2.1.3
access:
type: OCIImage/v1
imageReference: registry.company.com/user-service:2.1.3
- name: helm-chart
type: helmChart
version: 2.1.3
access:
type: Helm/v1
helmRepository: registry.company.com
helmChart: user-service-chart
version: 2.1.3
sources:
- name: source
type: git
access:
type: File/v1alpha1
uri: https://github.com/company/user-service
componentReferences:
- name: postgres
componentName: github.com/company/postgres
version: "14.9"
- name: redis
componentName: github.com/company/redis
version: "7.2"
This constructor captures artifacts, their sources, and component references — forming a complete, machine-readable bill of delivery that OCM can sign, verify, and transfer across registries.
Implementing Component Models for Supply Chain Security
Modern software supply chain security requires tracking components across their entire lifecycle. Here’s how component models address key security concerns:
Provenance Tracking
Component models maintain cryptographic proof of artifact origins:
type ComponentProvenance struct {
BuildSystem string `json:"buildSystem"`
SourceRepo string `json:"sourceRepo"`
CommitHash string `json:"commitHash"`
Builder string `json:"builder"`
BuildTime time.Time `json:"buildTime"`
Attestations []Attestation `json:"attestations"`
Signatures []Signature `json:"signatures"`
}
type Attestation struct {
Type string `json:"type"` // "build", "test", "security-scan"
Result string `json:"result"` // "pass", "fail", "warning"
Details string `json:"details"`
Timestamp time.Time `json:"timestamp"`
Verifier string `json:"verifier"`
}
Runtime Dependency Resolution
Unlike static SBOMs, component models track actual runtime dependencies:
# Runtime dependency discovery
runtimeDependencies:
discovered:
- service: payment-api
version: "1.4.2"
protocol: https
endpoint: payment-api.internal:443
discoveredAt: "2024-01-15T16:50:00Z"
declared:
- service: user-db
version: "14.9"
protocol: postgresql
endpoint: user-db.production:5432
external:
- service: stripe-api
endpoint: api.stripe.com
version: "2023-10-16"
sla: "99.9%"
Vulnerability Correlation
Component models enable precise vulnerability tracking across deployments:
{
"vulnerabilityReport": {
"component": "user-service:2.1.3",
"scanTime": "2024-01-15T17:00:00Z",
"findings": [
{
"cve": "CVE-2024-0001",
"severity": "high",
"affectedArtifacts": [
"container:user-service@sha256:8f8a8b8c8d8e8f"
],
"deploymentImpact": [
{
"environment": "production",
"instances": 5,
"exposure": "internal-only",
"mitigations": ["network-policy", "pod-security-policy"]
}
]
}
]
}
}
Distributed Systems and Component Relationships
In distributed architectures, understanding component relationships becomes crucial. Component models map these relationships explicitly:
Service Mesh Integration
componentRelationships:
upstreamServices:
- name: api-gateway
traffic: "100%"
protocol: http/2
downstreamServices:
- name: user-db
queries: ["SELECT", "UPDATE", "INSERT"]
connectionPool: 10
- name: notification-service
protocol: grpc
async: true
sidecarComponents:
- name: envoy-proxy
version: "1.28.0"
config: istio-proxy-config
- name: datadog-agent
version: "7.49.0"
config: monitoring-config
Cross-Cluster Dependencies
Modern applications span multiple clusters and cloud providers. Component models track these distributed relationships:
crossClusterDependencies:
- component: shared-cache
cluster: us-west-2-cache
endpoint: redis.shared.company.internal
latency: "< 5ms"
- component: analytics-pipeline
cluster: data-processing
protocol: kafka
topics: ["user-events", "audit-logs"]
- component: cdn
provider: cloudflare
endpoints: ["cdn.company.com"]
cachePolicies: ["static-assets", "api-responses"]
Automation and Tooling
Component models shine when integrated into automated workflows. Here’s how to implement automated delivery tracking:
CI/CD Integration
OCM uses a component-constructor.yaml file as input and the ocm add component-version command to push it into an OCI registry. Keys for signing are configured via .ocmconfig rather than passed as flags.
#!/bin/bash
# Build pipeline integration
set -e
# Build and push the container image
docker build -t registry.company.com/user-service:${BUILD_ID} .
docker push registry.company.com/user-service:${BUILD_ID}
# Write the component constructor
cat > component-constructor.yaml <<EOF
components:
- name: github.com/company/user-service
version: ${BUILD_ID}
provider:
name: company.com
labels:
- name: build.commit
value: ${GIT_COMMIT}
resources:
- name: container-image
type: ociImage
version: ${BUILD_ID}
access:
type: OCIImage/v1
imageReference: registry.company.com/user-service:${BUILD_ID}
sources:
- name: source
type: git
access:
type: File/v1alpha1
uri: https://github.com/company/user-service
EOF
# Add the component version to the OCM repository
ocm add component-version \
--repository ${OCI_REGISTRY} \
--constructor component-constructor.yaml
# Sign the component version (credentials configured in .ocmconfig)
ocm sign component-version \
${OCI_REGISTRY}//github.com/company/user-service:${BUILD_ID} \
--signature company-signature
Runtime Discovery
Automated discovery keeps component models current:
func discoverRuntimeDependencies(ctx context.Context, podName string) (*RuntimeDependencies, error) {
// Network traffic analysis
connections, err := analyzeNetworkConnections(podName)
if err != nil {
return nil, err
}
// Service mesh integration
envoyConfig, err := getEnvoyConfiguration(podName)
if err != nil {
return nil, err
}
// DNS resolution tracking
dnsQueries, err := analyzeDNSQueries(podName)
if err != nil {
return nil, err
}
return &RuntimeDependencies{
NetworkConnections: connections,
ServiceMeshRoutes: envoyConfig.Routes,
DNSResolutions: dnsQueries,
DiscoveredAt: time.Now(),
}, nil
}
Security Benefits and Compliance
Component models provide significant security advantages over traditional SBOMs:
Compliance Automation
CISA’s SBOM requirements focus on transparency, but component models enable automated compliance checking:
complianceChecks:
- policy: "no-high-severity-vulnerabilities"
status: "enforced"
lastCheck: "2024-01-15T18:00:00Z"
- policy: "signed-artifacts-only"
status: "enforced"
exceptions: []
- policy: "approved-base-images"
status: "warning"
violations:
- component: "legacy-service"
reason: "using deprecated base image"
Supply Chain Attack Detection
Component models enable sophisticated attack detection:
type SupplyChainAnomaly struct {
Type string `json:"type"`
Component string `json:"component"`
Description string `json:"description"`
Severity string `json:"severity"`
DetectedAt time.Time `json:"detectedAt"`
}
func detectAnomalies(current, previous *ComponentModel) []SupplyChainAnomaly {
var anomalies []SupplyChainAnomaly
// Unexpected dependency changes
for _, dep := range current.Dependencies {
if !containsDependency(previous.Dependencies, dep) {
anomalies = append(anomalies, SupplyChainAnomaly{
Type: "unexpected-dependency",
Component: current.Name,
Description: fmt.Sprintf("New dependency added: %s", dep.Name),
Severity: "medium",
DetectedAt: time.Now(),
})
}
}
// Build environment changes
if current.BuildEnvironment.Builder != previous.BuildEnvironment.Builder {
anomalies = append(anomalies, SupplyChainAnomaly{
Type: "builder-change",
Component: current.Name,
Description: "Build environment changed",
Severity: "high",
DetectedAt: time.Now(),
})
}
return anomalies
}
Implementation Roadmap
Moving from SBOMs to component models requires a phased approach:
Phase 1: SBOM Enhancement
Start by enriching existing SBOMs with delivery metadata. Integrate SBOM generation directly into CI/CD pipelines and add deployment context.
Phase 2: Component Model Adoption
Implement component descriptors alongside SBOMs. Begin tracking artifact relationships and deployment topology.
Phase 3: Runtime Integration
Deploy discovery agents to automatically update component models with runtime dependencies and actual service relationships.
Phase 4: Advanced Analytics
Implement anomaly detection, compliance automation, and predictive security analysis based on component model data.
The Future of Software Supply Chain Transparency
Software Bills of Delivery represent the evolution from static documentation to dynamic, living records of software components and their relationships. By implementing component models, organizations gain unprecedented visibility into their software supply chains, enabling proactive security, automated compliance, and confident deployment practices.
The shift from SBOMs to comprehensive component models isn’t just about better documentation—it’s about building software supply chains that are transparent, secure, and resilient by design. As distributed systems become more complex, this level of visibility becomes essential for maintaining security and operational excellence.
Component models provide the foundation for the next generation of software supply chain security tools, enabling organizations to move from reactive vulnerability management to proactive risk prevention. The question isn’t whether to adopt this approach, but how quickly you can implement it to stay ahead of emerging threats and compliance requirements.