Files
git.stella-ops.org/docs/modules/scanner/pedigree-support.md
2026-01-08 20:46:43 +02:00

223 lines
6.3 KiB
Markdown

# CycloneDX 1.7 Pedigree Support
> **Status:** Implementation in progress
> **Sprint:** SPRINT_20260107_005_002
> **Last Updated:** 2026-01-08
## Overview
StellaOps Scanner now supports native CycloneDX 1.7 `component.pedigree.*` fields, enabling detailed representation of component lineage, upstream ancestry, patch history, and commit provenance.
This integration connects Feedser's backport detection capabilities directly into the SBOM output, providing:
- **Ancestry tracking**: Links to upstream source packages
- **Variant mapping**: Distribution-specific package versions
- **Commit provenance**: Security fix commit references
- **Patch documentation**: Backport and cherry-pick evidence
## CycloneDX 1.7 Pedigree Structure
```json
{
"components": [
{
"type": "library",
"name": "openssl",
"version": "1.1.1n-0+deb11u5",
"purl": "pkg:deb/debian/openssl@1.1.1n-0+deb11u5",
"pedigree": {
"ancestors": [
{
"type": "library",
"name": "openssl",
"version": "1.1.1n",
"purl": "pkg:generic/openssl@1.1.1n"
}
],
"variants": [
{
"type": "library",
"name": "openssl",
"version": "1.1.1k-9.el9",
"purl": "pkg:rpm/rhel/openssl@1.1.1k-9.el9"
}
],
"commits": [
{
"uid": "abc123def456789",
"url": "https://github.com/openssl/openssl/commit/abc123",
"message": "Fix CVE-2024-1234"
}
],
"patches": [
{
"type": "backport",
"diff": {
"url": "https://salsa.debian.org/...",
"text": "--- a/crypto/x509/x509_vfy.c\n+++ b/crypto/x509/x509_vfy.c\n..."
},
"resolves": [
{
"type": "security",
"id": "CVE-2024-1234",
"source": { "name": "NVD" }
}
]
}
],
"notes": "Backported security fix from upstream 1.1.1o (CVE-2024-1234). Confidence: 95%. Tier 1 (exact match)."
}
}
]
}
```
## API Usage
### Basic Pedigree Lookup
```csharp
// Inject IPedigreeDataProvider
public class SbomEnricher(IPedigreeDataProvider pedigreeProvider)
{
public async Task EnrichAsync(Component component, CancellationToken ct)
{
var pedigree = await pedigreeProvider.GetPedigreeAsync(component.Purl, ct);
if (pedigree is not null)
{
var mapper = new CycloneDxPedigreeMapper();
component.Pedigree = mapper.Map(pedigree);
}
}
}
```
### Batch Pedigree Enrichment
```csharp
// Efficient batch lookup for multiple components
var purls = components.Select(c => c.Purl).ToList();
var pedigrees = await pedigreeProvider.GetPedigreesBatchAsync(purls, ct);
foreach (var component in components)
{
if (pedigrees.TryGetValue(component.Purl, out var data))
{
component.Pedigree = mapper.Map(data);
}
}
```
### Building Pedigree Data Manually
```csharp
// Use builders for custom pedigree construction
var ancestorBuilder = new AncestorComponentBuilder();
ancestorBuilder
.AddGenericUpstream("openssl", "1.1.1n", "https://www.openssl.org")
.AddGitHubUpstream("openssl", "openssl", "openssl-1.1.1n");
var variantBuilder = new VariantComponentBuilder();
variantBuilder
.AddDebianPackage("openssl", "1.1.1n-0+deb11u5", "bullseye", "amd64")
.AddRpmPackage("openssl", "1.1.1k-9.el9", "rhel", "9", "x86_64")
.AddAlpinePackage("openssl", "1.1.1t-r2", "3.17");
var commitBuilder = new CommitInfoBuilder();
commitBuilder
.AddGitHubCommit("openssl", "openssl", "abc123def", "Fix CVE-2024-1234");
var patchBuilder = new PatchInfoBuilder();
patchBuilder
.AddBackport(
diffUrl: "https://salsa.debian.org/...",
resolvesCves: new[] { "CVE-2024-1234" },
source: "debian-security");
var pedigree = new PedigreeData
{
Ancestors = ancestorBuilder.Build(),
Variants = variantBuilder.Build(),
Commits = commitBuilder.Build(),
Patches = patchBuilder.Build()
};
```
## Feedser Integration
### Tier Mapping
| Feedser Tier | Confidence | Description |
|--------------|------------|-------------|
| Tier 1 | 95-100% | Exact function signature match |
| Tier 2 | 80-94% | Changelog/commit message correlation |
| Tier 3 | 60-79% | Patch header/context match |
| Tier 4 | 40-59% | Binary fingerprint correlation |
| Tier 5 | 20-39% | NVD version range heuristic |
### Patch Origin Mapping
| Feedser Origin | CycloneDX Patch Type | Description |
|----------------|---------------------|-------------|
| `upstream` | `cherry-pick` | Direct cherry-pick from upstream |
| `distro` | `backport` | Distro-maintained backport |
| `vendor` | `unofficial` | Vendor-specific fix |
## Configuration
### Scanner Options
```yaml
scanner:
sbom:
pedigree:
enabled: true # Enable pedigree population
include_diff: true # Include patch diff text
max_diff_size: 50000 # Truncate large diffs
cache:
enabled: true
max_entries: 10000
sliding_expiration: 30m
absolute_expiration: 4h
```
### Environment Variables
```bash
# Enable/disable pedigree
STELLAOPS_SCANNER_PEDIGREE_ENABLED=true
# Cache configuration
STELLAOPS_PEDIGREE_CACHE_MAX_ENTRIES=10000
STELLAOPS_PEDIGREE_CACHE_TTL=4h
```
## Notes Field Format
The `pedigree.notes` field provides human-readable context:
```
Security patches: 2 backports resolving 3 CVEs.
Derived from upstream openssl 1.1.1n.
Variants exist for: alpine, debian, rhel.
Evidence: confidence 95%, Tier 1 (exact match).
Generated: 2026-01-08T12:00:00Z by StellaOps Feedser.
```
## Performance Considerations
1. **Batch lookups**: Use `GetPedigreesBatchAsync` for multiple components to avoid N+1 queries.
2. **Caching**: The `CachedPedigreeDataProvider` wraps the Feedser client with bounded MemoryCache.
3. **Negative caching**: Components without pedigree are cached with shorter TTL to reduce repeated lookups.
4. **Diff truncation**: Large patch diffs are automatically truncated with a link to the full source.
## See Also
- [CycloneDX 1.7 Specification - Pedigree](https://cyclonedx.org/docs/1.7/json/#components_items_pedigree)
- [Feedser Architecture](../feedser/architecture.md)
- [SBOM Generation Guide](./sbom-generation.md)