3.0 KiB
provenance
(no submodules)
Purpose
Generates SLSA v1.0 provenance statements wrapped in in-toto v1 envelopes. Each statement records the artifact digest, builder identity, source repository, git ref, and build timing — the tamper-evident audit trail that lets downstream consumers verify an artifact was built by a trusted pipeline from an expected source.
Features
- Canonical in-toto / SLSA v1.0 envelope shape.
- Deterministic serialisation through
canonicalize(sorted keys). - SHA-256 digest of the canonical encoding for signing / transparency logs.
- Builder version auto-detection (Bun in CI;
unknownelsewhere). - Structured
InvalidProvenanceErrorfor any malformed input. - OTel
slsa.provenance.generatedspan event with builder + source attributes.
Usage: Basic Example
import { generateProvenance, hashProvenance } from "@suaveplan/slsa";
const statement = generateProvenance({
packageName: "@suaveplan/utils",
packageVersion: "1.2.3",
artifactDigest: "abc123...",
sourceCommit: "deadbeef...",
sourceRepo: "https://gitlab.fq.io/suaveplan/project",
sourceRef: "refs/heads/main",
builderId: "https://gitlab.fq.io/suaveplan/project/-/runners/1",
buildInvocationId: "ci-12345",
buildStartedOn: new Date().toISOString(),
});
const digest = hashProvenance(statement);
Usage: Advanced Example
import {
createSlsaOtelAdapter,
generateProvenance,
serializeProvenance,
} from "@suaveplan/slsa";
const otel = createSlsaOtelAdapter();
const statement = generateProvenance({
/* ...fields... */,
resolvedDependencies: [
{
uri: "pkg:npm/lodash@4.17.21",
digest: { sha256: "lodashHashHex" },
name: "lodash",
},
],
otel,
});
await fs.writeFile("provenance.json", serializeProvenance(statement));
API Reference
generateProvenance(input: ProvenanceInput): ProvenanceStatement— validates all required fields, returns the in-toto envelope. ThrowsInvalidProvenanceErrorwhen any field is empty, non-string, or whenbuildStartedOn/buildFinishedOnare not parseable ISO 8601.serializeProvenance(statement): string— canonical (sorted-keys) JSON.hashProvenance(statement): string— SHA-256 hex of the canonical serialisation, used as the subject of Rekor hashedrekord entries.
Implementation Notes
buildType is pinned to https://suaveplan.app/slsa/build-type/bun-project/v1
— bumping this identifier is a semver break, since downstream verifiers may
pattern-match on it. resolvedDependencies is emitted at both
buildDefinition.resolvedDependencies and
buildDefinition.internalParameters.resolvedDependencies to match the two
common shapes found in GitHub's SLSA generator and the SLSA reference CLI.
Builder version detection uses globalThis.Bun rather than a top-level
import so the module is importable from non-Bun runtimes without a cold
failure. Hashing uses the same canonicalisation function as DSSE payload
encoding, so "the thing we signed" always matches "the thing we hashed".