Files
git.stella-ops.org/docs/modules/attestor/build-profile.md
2026-01-08 20:46:43 +02:00

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/)