CCSI

Lesson 8.2 · 13 min read

Reproducible builds and independent verification

Making builds deterministic so that a third party can rebuild and get the same measurement.

What reproducible means

A build is reproducible when building the same source with the same declared toolchain produces bit-for-bit identical output. For TEEs this is powerful: an auditor, customer or second build system can rebuild the image and confirm the published measurement independently, without trusting your CI.

Common sources of non-determinism

  • Timestamps embedded in archives, binaries or image layers
  • Unpinned base images (FROM ubuntu:latest) and package versions
  • File ordering and permissions differing between build hosts
  • Build paths or hostnames compiled into binaries
  • Network fetches during the build
dockerfile
# Pin the base image by digest, not by tag
FROM public.ecr.aws/amazonlinux/amazonlinux@sha256:<digest>
# Pin package versions and avoid network fetches after this point
COPY vendor/ /app/vendor/
COPY build/server /app/server
ENTRYPOINT ["/app/server"]
Pin inputs by digest to reduce drift
bash
# Two independent builds should print identical PCR values
nitro-cli build-enclave --docker-uri app:release --output-file app.eif
# Compare the PCR0/PCR1/PCR2 output with the published values
Independent rebuild check for a Nitro Enclave image

Key takeaways

  • Reproducible builds let third parties verify a measurement without trusting your CI.
  • Pin base images and dependencies by digest; remove timestamps and network fetches.
  • Compare measurements from two independent builds as a release gate.