They complicate it, but they do not make it impossible. A signature made with a private key cannot be regenerated by someone else, so a rebuilt artifact will differ from the signed one. Documented fixes are to treat the signature as an input, compare while ignoring it, or strip it before comparing.
Why signing seems to conflict
Reproducible builds rely on comparing bytes. The reproducible-builds documentation states the difficulty directly: with embedded cryptographic signatures, a user by definition cannot generate an identical signature. If your artifact contains one, a bit-for-bit comparison between your release and a user's rebuild always fails.
This matters for mobile apps, desktop installers and some package formats, where the signature lives inside the file. Detached signatures in a separate file do not have the problem, because the artifact itself is unchanged.
Three approaches
| Approach | How it works | Trade off |
|---|---|---|
| Paste the signature | Make the signature an optional build input. Developers build and sign once, store the signature, and the final build copies it into place | Extra release step, signature becomes part of the source release |
| Ignore signatures | A comparison tool skips the signature bytes | The tool must be simple to audit, otherwise it could be ignoring bytes that matter |
| Strip signatures | Ship a tool that removes the signature from the official release, then compare with the user's build | Needs a trusted stripping tool |
The documentation gives examples of each style. Debian handles one package by making the signature part of the released source, and F-Droid copies APK signatures onto its own builds using a dedicated tool.
Choosing one for a small team
- Prefer detached signatures where your format allows it. Then the artifact is unchanged and comparison is trivial.
- If the signature must be embedded, decide which verification story you want. If you want outsiders to verify, the paste approach gives them a straightforward recipe.
- If you build on a shared CI server, note that the signing key should not live in the same place as the code anyone can edit. Sign at the final step, with access controls.
- Publish the unsigned hash along with the signed hash, so a verifier knows which one to compare.
The checksum trick
The same documentation points out that identical bytes allow tiny checksums to be exchanged. It gives the example of building a release on a well-connected server that is hard to trust, and on a laptop on a poor connection, and signing locally on the laptop. As the products are identical, the laptop's signature is valid for the files from the server. That is a useful pattern if you want builds in CI but signatures from a controlled machine.
What to avoid
Do not write a comparison script that quietly skips a range of bytes you have not looked at. The documentation warns that such a tool must be very easy to audit and understand. If nobody on the team can explain what it ignores, it is not evidence.
Where Safeguard fits
Signing and verification are outside what Safeguard does. It supports the dependency side with SBOMs and scanning, which you can run on the unsigned build. Free scan: gold.safeguard.sh/scan.
Quick check
Do detached signatures have this problem?
No. The artifact stays unmodified, so a rebuild can match it byte for byte.
Is a reproducible build useless if we sign?
No. You can still compare the unsigned content, or use one of the documented methods to handle the signature.
Sources
Last reviewed: 19 October 2026.