# 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; `unknown` elsewhere). - Structured `InvalidProvenanceError` for any malformed input. - OTel `slsa.provenance.generated` span event with builder + source attributes. ## Usage: Basic Example ```ts 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 ```ts 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. Throws `InvalidProvenanceError` when any field is empty, non-string, or when `buildStartedOn` / `buildFinishedOn` are 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".