Safeguard
Developer Tools•

How do you handle randomness and UUIDs in a reproducible build?

Random values written into build output make every build differ. Replace them with a seeded generator whose seed comes from the source revision.

Safeguard Security Team
4 min read

Do not write random values into build output. If you need something random looking, such as an identifier, seed a pseudo-random generator with a fixed value taken from the source, like a file, a changelog or the commit. Then every build of the same source produces the same values.

Where randomness hides

The reproducible-builds documentation says random data will make builds unreproducible and must be avoided. Common places it appears:

  • Unique identifiers generated for a package, installer or filesystem.
  • Build ids and hash seeds that tools generate on the fly.
  • Temporary file names that end up recorded in output. The documentation notes intermediate temporary files can lead to paths embedded in the final output.
  • Link time optimization, where the documentation says GCC users write random identifiers into object files, and a random seed option can be given to fix that.
  • Filesystem images, where UUIDs and labels not set explicitly make images differ. The system image guidance lists unset UUIDs and labels as a general problem and shows setting hash seeds and UUIDs explicitly when creating a filesystem, and a deterministic seed variable for one filesystem tool.

The commandments phrase it as a rule: do not gamble and record random numbers such as UUIDs, keys, hash seeds or address layout values.

The standard fix

Replace "generate random" with "derive from the source".

  1. Choose a seed source. The documentation suggests reading the value from a file, a changelog or version control. A commit id is a good choice because it is unique to the source and fixed.
  2. Seed a pseudo-random generator with that value, and use it wherever the build needs an arbitrary value.
  3. Or derive the value directly. A name based identifier computed from a stable string, such as the project name plus version, gives the same result every time.
  4. Document the choice so a new developer does not "improve" it back to random.
import hashlib, subprocess
commit = subprocess.check_output(["git","rev-parse","HEAD"]).decode().strip()
build_id = hashlib.sha256(("myapp:" + commit).encode()).hexdigest()[:32]

Treat this as a build identifier alone. Do not use a derived value where you need real secrecy, such as a signing key or an access token.

What must stay random

Some values must be random at runtime: session tokens, encryption keys, nonces. Reproducibility is about the build, not the running program. The distinction to hold: values generated when the software runs are fine, values frozen into the artifact during the build should be derived.

ValueAt build timeAt run time
Artifact identifierDerive from sourcen/a
Filesystem UUID in an imageSet explicitlyn/a
Session tokenNever bake inGenerate randomly
Signing keyNever derive from sourceGenerate and store securely

Finding the culprits

  1. Build twice and compare the outputs with a byte level diff tool.
  2. Look at the differing regions. Hex strings that look like identifiers are the usual sign.
  3. Search the build scripts and tool options for a seed or identifier setting.
  4. Set it explicitly and rebuild.

Where Safeguard fits

Safeguard scans dependencies and produces SBOMs rather than inspecting build identifiers. Free scan: gold.safeguard.sh/scan.

Quick check

Is a derived identifier as unique as a random one?

It is unique per source revision, which is what a build identifier needs. It is not suitable for secrets.

Should tests also avoid randomness?

Tests can use random inputs, but log the seed so a failing run can be repeated.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.