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

5.9 KiB

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:

{
  "@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:

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:

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:

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:

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:

{
  "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:

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 for details.