more audit work

This commit is contained in:
master
2026-01-08 10:21:51 +02:00
parent 43c02081ef
commit 51cf4bc16c
546 changed files with 36721 additions and 4003 deletions

View File

@@ -0,0 +1,213 @@
# SPDX 3.0.1 Build Profile Integration
> **Sprint:** SPRINT_20260107_004_003_BE
> **Status:** Active
> **Last Updated:** 2026-01-08
## Overview
The SPDX 3.0.1 Build profile captures provenance information about how an artifact was built. StellaOps integrates this profile with the Attestor module, enabling generation of build attestations that conform to both SPDX 3.0.1 and existing DSSE/in-toto standards.
This creates a unified build provenance format that:
- Aligns with SLSA provenance levels
- Integrates with existing DSSE signing infrastructure
- Can be combined with Software profile SBOMs into single documents
## Build Profile Structure
### Core Build Element
The `Spdx3Build` element represents build/CI information:
```json
{
"@type": "Build",
"spdxId": "urn:stellaops:build:abc123",
"build_buildType": "https://stellaops.org/build/container-scan/v1",
"build_buildId": "build-12345",
"build_buildStartTime": "2026-01-07T12:00:00Z",
"build_buildEndTime": "2026-01-07T12:05:00Z",
"build_configSourceUri": ["https://github.com/..."],
"build_configSourceDigest": [{"algorithm": "sha256", "hashValue": "..."}],
"build_configSourceEntrypoint": [".github/workflows/build.yml"],
"build_environment": {"CI": "true"},
"build_parameter": {"target": "release"}
}
```
### Property Mapping
| SLSA/in-toto | SPDX 3.0.1 Build |
|--------------|------------------|
| buildType | build_buildType |
| builder.id | CreationInfo.createdBy (Agent) |
| invocation.configSource.uri | build_configSourceUri |
| invocation.configSource.digest | build_configSourceDigest |
| invocation.configSource.entryPoint | build_configSourceEntrypoint |
| invocation.environment | build_environment |
| invocation.parameters | build_parameter |
| metadata.buildStartedOn | build_buildStartTime |
| metadata.buildFinishedOn | build_buildEndTime |
| metadata.buildInvocationId | build_buildId |
## API Usage
### Mapping Attestations
Use `BuildAttestationMapper` to convert between SLSA/in-toto and SPDX 3.0.1:
```csharp
var mapper = new BuildAttestationMapper();
// From in-toto to SPDX 3.0.1
var attestation = new BuildAttestationPayload
{
BuildType = "https://slsa.dev/provenance/v1",
Metadata = new BuildMetadata
{
BuildInvocationId = "run-12345",
BuildStartedOn = DateTimeOffset.UtcNow
}
};
var build = mapper.MapToSpdx3(attestation, "https://stellaops.io/spdx");
// From SPDX 3.0.1 to in-toto
var payload = mapper.MapFromSpdx3(build);
```
### Signing with DSSE
Use `DsseSpdx3Signer` to sign SPDX 3.0.1 documents:
```csharp
var signer = new DsseSpdx3Signer(serializer, signingProvider, timeProvider);
var options = new DsseSpdx3SigningOptions
{
PrimaryKeyId = "key-123",
PrimaryAlgorithm = "ES256",
// Optional: Add post-quantum hybrid signature
SecondaryKeyId = "pq-key-456",
SecondaryAlgorithm = "ML-DSA-65"
};
// Sign a Build element
var envelope = await signer.SignBuildProfileAsync(build, null, options);
// Or sign a full document
var envelope = await signer.SignAsync(document, options);
```
### Combined Documents
Use `CombinedDocumentBuilder` to merge profiles:
```csharp
var document = CombinedDocumentBuilder.Create(timeProvider)
.WithDocumentId("https://stellaops.io/spdx/combined/12345")
.WithName("Combined SBOM and Build Provenance")
.WithSoftwareProfile(sbom)
.WithBuildProfile(build)
.Build();
// Or use the extension method
var combined = sbom.WithBuildProvenance(
attestation,
documentId: "https://stellaops.io/spdx/combined/12345",
spdxIdPrefix: "https://stellaops.io/spdx");
```
## SLSA Alignment
The SPDX 3.0.1 Build profile supports SLSA provenance levels:
| SLSA Level | SPDX 3.0.1 Support |
|------------|-------------------|
| SLSA 1 | Build element with buildType, configSourceUri |
| SLSA 2 | + Signed document (DSSE), builder Agent |
| SLSA 3 | + Hermetic build (environment isolation) |
| SLSA 4 | + Two-party review (external verification) |
## Build Relationships
The following relationships connect Build elements to other SPDX elements:
| Relationship | Direction | Description |
|-------------|-----------|-------------|
| GENERATES | Build -> Package | Build produces this artifact |
| GENERATED_FROM | Package -> File | Artifact was built from these sources |
| BUILD_TOOL_OF | Tool -> Build | Tool was used in this build |
Example relationship generation:
```csharp
var relationships = new BuildRelationshipBuilder(build.SpdxId)
.Generates(packageId)
.GeneratedFrom(sourceFileIds)
.UsedBuildTool(toolId)
.Build();
```
## DSSE Envelope Format
The DSSE envelope wraps the entire SPDX 3.0.1 document:
```json
{
"payloadType": "application/spdx+json",
"payload": "<base64url-encoded SPDX 3.0.1 JSON>",
"signatures": [
{
"keyid": "key-123",
"sig": "<base64url-encoded signature>"
}
]
}
```
### PAE (Pre-Authentication Encoding)
Signatures are computed over the PAE:
```
DSSEv1 <len(payloadType)> <payloadType> <len(payload)> <payload>
```
This prevents ambiguity attacks and ensures the payload type is included in the signature.
## Verification
To verify a signed SPDX 3.0.1 envelope:
```csharp
var trustedKeys = new List<DsseVerificationKey>
{
new() { KeyId = "key-123", PublicKey = publicKeyBytes }
};
var isValid = await signer.VerifyAsync(envelope, trustedKeys);
if (isValid)
{
var document = signer.ExtractDocument(envelope);
// Process verified document
}
```
## Offline Support
The Build profile integration supports air-gapped environments:
- All cryptographic operations can use offline key material
- No network calls required for signing or verification
- Documents can be bundled for offline transport
See [Attestor Air-Gap Guide](./airgap.md) for details.
## Related Documentation
- [Attestor Architecture](./architecture.md)
- [DSSE Roundtrip Verification](./dsse-roundtrip-verification.md)
- [in-toto Link Guide](./intoto-link-guide.md)
- [SPDX 3.0.1 Specification](https://spdx.github.io/spdx-spec/v3.0.1/)

View File

@@ -81,7 +81,7 @@ The starter policy implements a sensible security posture:
### Rule 3: Allow Unreachable
```yaml
- name: ignore-unreachable
- name: allow-unreachable
description: "Allow unreachable vulnerabilities but log for awareness"
match:
reachability: unreachable
@@ -165,16 +165,14 @@ spec:
settings:
defaultAction: warn # Never block in dev
unknownsThreshold: 0.20 # Allow more unknowns (20%)
requireSignedSbom: false
requireSignedVerdict: false
ruleOverrides:
- name: block-reachable-high-critical
action: warn # Downgrade to warn
- name: require-signed-sbom-prod
enabled: false # Disable signing requirements
- name: require-signed-verdict-prod
enabled: false
- name: block-kev
action: warn
```
### Staging (`overrides/staging.yaml`)
@@ -189,11 +187,10 @@ metadata:
spec:
settings:
defaultAction: warn
unknownsThreshold: 0.10 # 10% unknowns budget
ruleOverrides:
- name: require-signed-sbom-prod
enabled: false # No signing in staging
requireSignedSbom: false
requireSignedVerdict: false
```
### Production (Default)

View File

@@ -0,0 +1,20 @@
### Identity
You are an autonomous software engineering agent for StellaOps working on Router sample projects in docs.
### Roles
- Document author
- Backend developer (.NET 10)
- Tester/QA automation engineer
### Required reading
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/router/architecture.md
### Working agreements
- Scope is limited to `docs/modules/router/samples/**` unless a sprint explicitly allows cross-module edits.
- Samples must remain deterministic and ASCII-only; avoid non-ASCII glyphs in logs.
- Samples are documentation assets; changes should preserve their instructional value.
### Testing
- Sample projects are not part of the main solution; tests are optional and should be documented if added.

View File

@@ -0,0 +1,222 @@
# 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)

View File

@@ -0,0 +1,221 @@
# SPDX 3.0.1 Security Profile Integration
> **Sprint:** SPRINT_20260107_004_004_BE
> **Status:** Active
> **Last Updated:** 2026-01-08
## Overview
The SPDX 3.0.1 Security profile captures vulnerability assessment information in a standardized format. StellaOps VexLens integrates this profile to export VEX consensus data in SPDX 3.0.1 format, enabling interoperability with SPDX-compatible tooling.
This creates a unified security assessment format that:
- Aligns with OpenVEX semantics
- Integrates with existing SBOM documents
- Supports CVSS and EPSS scoring
- Enables combined Software+Security profile documents
## Security Profile Elements
### Vulnerability Element
The `Spdx3Vulnerability` element represents a security vulnerability:
```json
{
"@type": "security_Vulnerability",
"spdxId": "urn:stellaops:vuln:CVE-2026-1234",
"name": "CVE-2026-1234",
"summary": "Remote code execution in example library",
"security_publishedTime": "2026-01-01T00:00:00Z",
"security_modifiedTime": "2026-01-05T12:00:00Z",
"externalIdentifier": [{
"externalIdentifierType": "cve",
"identifier": "CVE-2026-1234",
"identifierLocator": ["https://nvd.nist.gov/vuln/detail/CVE-2026-1234"]
}]
}
```
### VEX Assessment Relationships
VEX assessments are modeled as relationships between vulnerabilities and products:
| OpenVEX Status | SPDX 3.0.1 Type | Relationship |
|----------------|-----------------|--------------|
| affected | VexAffectedVulnAssessmentRelationship | Affects |
| not_affected | VexNotAffectedVulnAssessmentRelationship | DoesNotAffect |
| fixed | VexFixedVulnAssessmentRelationship | FixedIn |
| under_investigation | VexUnderInvestigationVulnAssessmentRelationship | UnderInvestigationFor |
Example affected assessment:
```json
{
"@type": "security_VexAffectedVulnAssessmentRelationship",
"spdxId": "urn:stellaops:vex/CVE-2026-1234/pkg-abc",
"security_assessedElement": "urn:stellaops:pkg/abc",
"from": "urn:stellaops:vuln:CVE-2026-1234",
"to": ["urn:stellaops:pkg/abc"],
"relationshipType": "affects",
"security_vexVersion": "1.0.0",
"security_statusNotes": "Vulnerable code path is exposed",
"security_actionStatement": "Upgrade to version 2.0.0",
"security_actionStatementTime": "2026-01-15T00:00:00Z"
}
```
### Justification Types
For `not_affected` status, SPDX 3.0.1 supports these justification types:
| OpenVEX Justification | SPDX 3.0.1 JustificationType |
|----------------------|------------------------------|
| component_not_present | ComponentNotPresent |
| vulnerable_code_not_present | VulnerableCodeNotPresent |
| vulnerable_code_cannot_be_controlled_by_adversary | VulnerableCodeCannotBeControlledByAdversary |
| vulnerable_code_not_in_execute_path | VulnerableCodeNotInExecutePath |
| inline_mitigations_already_exist | InlineMitigationsAlreadyExist |
## API Usage
### Mapping VEX Consensus
Use `VexToSpdx3Mapper` to convert VEX consensus to SPDX 3.0.1:
```csharp
var mapper = new VexToSpdx3Mapper(timeProvider);
var consensus = new VexConsensus
{
DocumentId = "urn:stellaops:vex:doc-12345",
Author = "security-team@example.com",
Statements = statements
};
var options = new VexToSpdx3Options
{
SpdxIdPrefix = "https://stellaops.io/spdx",
IncludeCvss = true,
IncludeEpss = true,
ProductFilter = null // All products
};
var document = await mapper.MapConsensusAsync(consensus, options);
```
### Combined SBOM+VEX Documents
Use `CombinedSbomVexBuilder` to merge Software and Security profiles:
```csharp
var document = CombinedSbomVexBuilder.Create(timeProvider)
.WithDocumentId("https://stellaops.io/spdx/combined/12345")
.WithName("Combined SBOM and VEX Data")
.WithSoftwareProfile(sbom)
.WithSecurityProfile(consensus, spdxIdPrefix)
.Build();
// Or use the extension method
var combined = sbom.WithVexData(
consensus,
documentId: "https://stellaops.io/spdx/combined/12345",
spdxIdPrefix: "https://stellaops.io/spdx");
```
### Linked Security Profile
When combining SBOM and VEX, product IDs (PURLs) are automatically linked to SPDX Package IDs:
```csharp
var combined = CombinedSbomVexBuilder.Create()
.WithDocumentId(documentId)
.WithSoftwareProfile(sbom) // Extracts PURL->SPDX ID mapping
.WithLinkedSecurityProfile(statements, spdxIdPrefix) // Rewrites product IDs
.Build();
```
## CVSS Integration
CVSS v3 scores are mapped to `CvssV3VulnAssessmentRelationship`:
```json
{
"@type": "security_CvssV3VulnAssessmentRelationship",
"spdxId": "urn:stellaops:cvss/CVE-2026-1234",
"security_assessedElement": "urn:stellaops:pkg/abc",
"from": "urn:stellaops:vuln:CVE-2026-1234",
"to": ["urn:stellaops:pkg/abc"],
"security_score": 9.8,
"security_severity": "Critical",
"security_vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
}
```
Severity is automatically calculated from score:
- 0.0: None
- 0.1-3.9: Low
- 4.0-6.9: Medium
- 7.0-8.9: High
- 9.0-10.0: Critical
## EPSS Integration
EPSS (Exploit Prediction Scoring System) data is mapped to `EpssVulnAssessmentRelationship`:
```json
{
"@type": "security_EpssVulnAssessmentRelationship",
"spdxId": "urn:stellaops:epss/CVE-2026-1234",
"security_assessedElement": "urn:stellaops:pkg/abc",
"from": "urn:stellaops:vuln:CVE-2026-1234",
"to": ["urn:stellaops:pkg/abc"],
"security_probability": 0.85,
"security_percentile": 0.97
}
```
## Parsing Security Profile
The `Spdx3Parser` can parse SPDX 3.0.1 documents containing Security profile elements:
```csharp
var parser = new Spdx3Parser(contextResolver, logger);
var result = await parser.ParseAsync(stream);
if (result.IsSuccess)
{
var vulnerabilities = result.Document.Elements
.OfType<Spdx3Vulnerability>();
var vexAssessments = result.Document.Relationships
.OfType<Spdx3VulnAssessmentRelationship>();
}
```
## OpenVEX Interoperability
VexLens maintains full interoperability between OpenVEX and SPDX 3.0.1:
| Feature | OpenVEX | SPDX 3.0.1 Security |
|---------|---------|---------------------|
| Status values | 4 statuses | 4 relationship types |
| Justifications | 5 types | 5 justification types |
| Action statements | Supported | Supported |
| Timestamps | Supported | Supported |
| CVSS | Embedded | Separate relationship |
| EPSS | Custom extension | Separate relationship |
## Offline Support
The Security profile integration supports air-gapped environments:
- All mapping operations are local
- No network calls required for document generation
- Documents can be bundled for offline transport
## Related Documentation
- [VexLens Architecture](./architecture.md)
- [OpenVEX Guide](../../VEX_CONSENSUS_GUIDE.md)
- [Attestor Build Profile](../attestor/build-profile.md)
- [SPDX 3.0.1 Specification](https://spdx.github.io/spdx-spec/v3.0.1/)