Files
suaveplan/openspec/archive/2026-04-19-enterprise-slsa/proposal.md
2026-05-27 23:29:53 +01:00

3.7 KiB

OpenSpec Change: enterprise-slsa

  • Change ID: enterprise-slsa
  • Package: @suaveplan/slsa
  • Category: universal / auth
  • Target path: universal/auth/slsa
  • Status: SHIPPED
  • Date: 2026-04-19

Why

The genesis @suaveplan/slsa package previously shipped a thin, flat src/lib/*.ts layout that produced in-toto/SLSA provenance, verified it against a policy, emitted CycloneDX 1.5 SBOMs, and assessed the build environment. That surface is foundational but well short of the CLAUDE.md target for the package, which calls out DSSE attestation envelopes, a Sigstore Rekor transparency-log client (upload + inclusion proof verification), a composite policy evaluator, structured errors via @suaveplan/error, Zod schemas on every wire-format type, OTel audit events, and the standard four-file feature-module layout.

What Changes

ADDED

  • Four-file co-located feature-module layout under universal/auth/slsa/src/<category>/<feature>/.
  • Structured errors: SlsaError base + stable SLSA.* code registry via defineCodes, plus per-domain subclasses (InvalidProvenanceError, InvalidSbomError, VerificationFailedError, PolicyViolationError, RekorUploadError, RekorInclusionError, AttestationInvalidError, EnvironmentUnsupportedError).
  • Zod schemas for every wire-format type: ProvenanceStatementSchema, SlsaProvenancePredicateSchema, BuildDefinitionSchema, RunDetailsSchema, BuilderSchema, BuildMetadataSchema, ResourceDescriptorSchema, DigestSetSchema, VerificationPolicySchema, VerificationResultSchema, SbomSchema, SbomComponentSchema, SbomInputSchema, SlsaAssessmentSchema, AssessmentEnvironmentSchema, RekorEntrySchema, InclusionProofSchema, DsseEnvelopeSchema, AttestationSchema with parseProvenance / parseSbom helpers.
  • DSSE PAE + envelope: encodeDssePae, wrapInDsse, verifyDsseEnvelope (ed25519, keyid-scoped trust).
  • Sigstore Rekor client: RekorClient with injectable fetch, uploadHashedrekord / uploadIntoto (v0.0.2), getEntryByUuid / getEntryByLogIndex, verifyInclusionProof (RFC 6962 with 0x00/0x01 domain separators, odd-size carry-up).
  • Composite policy evaluator evaluatePolicy layering verifyProvenance + DSSE signatures + Rekor inclusion + min SLSA level.
  • OTel audit adapter: createSlsaOtelAdapter emitting slsa.provenance.generated, slsa.provenance.verified, slsa.rekor.upload, slsa.rekor.inclusion_verified, slsa.policy.violation.
  • Canonical JSON helper (canonicalize) for deterministic hashing / signing.
  • computeDigest routed through @suaveplan/crypto-hash — no direct node:crypto imports.
  • Rekor-inclusion signal on the L3 assessment gate.
  • Per-feature subpath exports in package.json.
  • Root README.md linking every co-located module .md.

REMOVED

  • src/lib/*.ts flat layout and its node:crypto digest path.
  • Plain new Error(...) throws in favour of structured SlsaError subclasses.

Impact

  • @suaveplan/slsa gains workspace deps @suaveplan/error, @suaveplan/types, @suaveplan/crypto, @suaveplan/crypto-hash, @suaveplan/crypto-utils, @suaveplan/serialize, plus @opentelemetry/api and zod from catalogs.
  • Downstream consumers (publish pipeline, release gates) can now call evaluatePolicy for a single pass/fail decision and will receive typed errors with instanceof narrowing.
  • No other packages depend on @suaveplan/slsa today, so there is no cross-package migration burden.

Verification

  • bunx turbo lint typecheck test --filter=@suaveplan/slsa — all green.
  • Istanbul coverage: 99.2% statements, 100% functions, 99.44% lines, 95.15% branches. Meets the 95% floor on every axis.
  • 13 test files, 170 test cases.