A build is hermetic when the same source and configuration always produce the same output, because the build is isolated from whatever happens to be installed on the host. To test yours, build twice, build on a second machine, build in a bare container, and compare file hashes.
Definition in plain words
Bazel's documentation describes two parts of hermeticity. The first is isolation: tools are treated like source code, downloaded and stored in managed file trees, so the host machine and its installed language versions do not leak in. The second is source identity: the build tries to make sure its inputs are the same, using hashes rather than names such as "latest".
For supply chain work, this matters because a hermetic build has a short, explicit list of what it consumed. That list is what you scan, sign and audit. A non-hermetic build reads from places nobody wrote down.
Five checks you can run this week
| Check | What you do | What a failure tells you |
|---|---|---|
| Null rebuild | Run the build, then run it again unchanged | Something rebuilds without an input changing |
| Second machine | Build on another host and compare output hashes | Host tools or paths leak into outputs |
| Bare container | Build in a container holding only the source and a stated list of tools | An implicit system dependency exists |
| Strict sandbox | Turn on per-action sandboxing | An action reads files it never declared |
| Log the risky steps | Log workspace or repository rule activity | Arbitrary processing runs during fetch |
These are the same strategies the Bazel hermeticity page recommends for finding non-hermetic behavior: ensure null sequential builds, run from different client machines, build inside a container with nothing but the checked out tree and an explicit list of host tools, and enable strict sandboxing.
Common sources of non-hermeticity
The same page lists the usual culprits:
- Actions that create files non-deterministically, often with build IDs or timestamps.
- System binaries that differ across hosts, such as compilers under /usr/bin or absolute paths.
- Writing into the source tree during the build.
- Arbitrary processing in make files or workspace rules.
Add a fifth from experience, not from the docs: install scripts that call the network. Any step that fetches without a pinned hash is a place where the answer can change between Tuesday and Wednesday.
What a pass does and does not prove
A hermetic build is not a safe build. It will faithfully reproduce a compromised dependency if the pinned input was compromised on the day you pinned it. What hermeticity gives you is evidence and repeatability: you can say exactly what went in, and you can rebuild it to check.
Think of it as the base layer. On top you still need dependency review, advisory monitoring and a way to answer "which of our builds consumed this version?" after an incident.
Where Safeguard fits
Safeguard can inventory the dependencies your repository declares through SBOM and dependency scanning, and reachability analysis helps you decide which findings matter first. You can try a free scan on a repository to see what it finds. Check coverage for your specific build files before relying on it.
Try it yourself
Open the demo and look at how many components a single project resolves. Each one is an input your build must pin to stay hermetic.
Click through it at your own pace, or open it full screen.
Quick check
Is a reproducible build the same as a hermetic build?
No. Hermetic describes isolation from the host. Reproducible describes getting identical output bits. Hermeticity is usually needed for reproducibility but does not guarantee it.
Do I need Bazel to have a hermetic build?
No. Any build can be improved by pinning tools, avoiding host binaries and building in a clean container. Bazel enforces more of it by design.
Sources
Last reviewed: 19 October 2026.