Skip to content

Define evidence bundle format and emit via aicr validate --emit-evidence #754

@mchmarny

Description

@mchmarny

Parent: #750
Depends on: cluster fingerprint child issue (filed alongside), #739 (BOM)

Summary

Define a versioned, signed evidence bundle format and add aicr validate --emit-evidence <out> that produces it. The bundle is what a community contributor attaches to a recipe PR; aicr verify-evidence (separate child issue) consumes it.

Format — in-toto attestation with custom AICR predicate

The bundle is a single tar.gz archive whose payload is an in-toto Statement carrying a custom predicate. The Statement is signed via cosign keyless OIDC (matching aicr bundle --attest); KMS support is deferred.

Predicate type: https://aicr.nvidia.com/recipe-evidence/v1

Predicate fields (illustrative):

{
  "_type": "https://in-toto.io/Statement/v1",
  "predicateType": "https://aicr.nvidia.com/recipe-evidence/v1",
  "subject": [{
    "name": "recipe:<recipe-name>",
    "digest": { "sha256": "<canonical-recipe-yaml-hash>" }
  }],
  "predicate": {
    "schemaVersion": "1.0.0",
    "aicrVersion": "<v>",
    "validatorCatalogVersion": "<v>",
    "validatorImages": { "<name>": "<digest>" },
    "recipe": "<canonical YAML>",
    "snapshot": "<snapshot YAML>",
    "fingerprint": { ... },
    "fingerprintMatch": { "matched": true, "diff": [] },
    "phases": {
      "deployment": { "status": "passed", "ctrf": {...}, "logs": [...] },
      "performance": { "status": "passed", "ctrf": {...}, "logs": [...] },
      "conformance": { "status": "passed", "ctrf": {...}, "logs": [...] }
    },
    "bom": { "ref": "bom.cdx.json", "digest": "sha256:..." },
    "manifest": { "files": [...], "hashes": {...} }
  }
}

The tarball layout:

evidence-bundle.tar.gz
├── attestation.intoto.jsonl    # signed in-toto Statement
├── recipe.yaml                  # subject material
├── snapshot.yaml                # subject material
├── bom.cdx.json                 # CycloneDX from #739
├── phases/
│   ├── deployment/{ctrf.json, logs/*}
│   ├── performance/{ctrf.json, logs/*}
│   └── conformance/{ctrf.json, logs/*}
└── manifest.json                # file inventory + content hashes

The attestation references content by hash; the supporting files are bundled alongside for reviewer convenience and offline verification.

Why in-toto + cosign

  • Sigstore tooling verifies it natively today.
  • Custom predicate gives us schema control without forking standards.
  • Path forward to SLSA Verification Summary Attestation (VSA) interop later — a VSA can be derived from this bundle.
  • Rekor transparency log entry on signing gives durable third-party-verifiable provenance.

Proposed approach

  1. Specify the schema as a versioned JSON Schema document under docs/spec/recipe-evidence-v1.md (or api/). Treat it as a public stability boundary.
  2. Implement pkg/evidence/bundle (or extend pkg/evidence) with a Build(ctx, opts) (Bundle, error) API that takes recipe + snapshot + per-phase results + BOM and returns a signed bundle.
  3. Wire aicr validate --emit-evidence <out> so a successful (or even failed — still useful) validation run produces the bundle.
  4. Use cosign keyless OIDC by default; make the signing surface pluggable so KMS can land later without breaking callers.
  5. Cover with unit tests for predicate construction + integration tests for end-to-end bundle creation against a kwok cluster.

Success criteria

  • aicr validate --recipe r.yaml --snapshot s.yaml --emit-evidence ./out/ produces a single tar.gz containing the signed in-toto attestation and supporting material.
  • The attestation is verifiable with vanilla cosign verify-blob-attestation against the public Rekor log (no AICR-specific tooling needed for raw verification).
  • Schema is documented and versioned; predicate type is https://aicr.nvidia.com/recipe-evidence/v1.
  • Round-trip test: the bundle can be unpacked, the predicate parsed, every referenced file's digest matches, and the recipe-snapshot fingerprint binding holds.

Out of scope

  • The verifier UX (aicr verify-evidence) — separate child issue.
  • KMS-backed signing — future extension.
  • Long-term storage / hosting of bundles.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions