214 lines
5.9 KiB
Markdown
214 lines
5.9 KiB
Markdown
# 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/)
|