Files
skills/docs/security-stack/security/slsa/src/rekor/inclusion-proof.md
2026-05-29 08:20:56 +01:00

2.6 KiB

inclusion-proof

Purpose

Verifies an RFC 6962 Merkle inclusion proof as returned by Sigstore Rekor. Given a leaf (the canonical body a Rekor entry was logged as), a sibling audit path, the leaf's log index, the tree size at inclusion time, and the signed root hash, recomputes the root and confirms it matches. This is the cryptographic half of Rekor trust — once the root matches, the transparency log has published the entry and cannot later lie about having done so.

Features

  • RFC 6962 hashing with explicit domain separators (0x00 for leaves, 0x01 for interior nodes).
  • Correct handling of last-node-at-level carrying (odd tree sizes).
  • Structured RekorInclusionError when logIndex is out of range.
  • Exposes rfc6962LeafHash for batch / cache use-cases.

Usage: Basic Example

import { verifyRfc6962InclusionProof } from "@suaveplan/slsa";

const { valid, computedRootHex } = verifyRfc6962InclusionProof({
  leafBytes: new TextEncoder().encode(entry.body),
  hashes: entry.verification.inclusionProof.hashes,
  logIndex: entry.logIndex,
  treeSize: entry.verification.inclusionProof.treeSize,
  expectedRootHex: entry.verification.inclusionProof.rootHash,
});

Usage: Advanced Example

import {
  RekorClient,
  rfc6962LeafHash,
  verifyRfc6962InclusionProof,
} from "@suaveplan/slsa";

const client = new RekorClient();
const entry = await client.uploadHashedrekord(rekord);
const leafBytes = new TextEncoder().encode(entry.body);

const leafHex = rfc6962LeafHash(leafBytes);
log.info({ leafHex, logIndex: entry.logIndex }, "rekor entry hashed");

const proof = entry.verification?.inclusionProof;
if (proof) {
  const { valid } = verifyRfc6962InclusionProof({
    leafBytes,
    hashes: proof.hashes,
    logIndex: entry.logIndex,
    treeSize: proof.treeSize,
    expectedRootHex: proof.rootHash,
  });
  if (!valid) throw new Error("inclusion failed");
}

API Reference

  • verifyRfc6962InclusionProof(args): { valid, computedRootHex } — returns whether the computed root matches. Throws RekorInclusionError when logIndex >= treeSize or logIndex < 0.
  • rfc6962LeafHash(body: Uint8Array): string — lowercase hex SHA-256 with the 0x00 leaf prefix.

Implementation Notes

The carry-up branch (odd-count level) handles trees where the last node at a given level has no sibling — rather than duplicating, RFC 6962 propagates the node up unchanged. Rekor's server-side proof generator will either produce a shorter path for such leaves or include a duplicate; this implementation tolerates the former. String comparison is case-insensitive on the expected root to match Sigstore's mixed-case hex output.