FIPS
fips = true is a truthfulness contract, not a switch that makes a build FIPS.
This page is short on purpose, because the honesty of the flag matters more than
anything else about it.
What fips = true actually does
Passing fips = true to mkHardenedImage / mkSecureArtifact builds the
wrapping image under the FIPS package set, which flips buildGitlabImage’s FIPS
marker so the image carries FIPS OCI labels
(e.g. com.gitlab.image.fips = "true").
That is all it does. It applies labels. It does not convert a non-FIPS build into a FIPS one.
The contract
The flag is a promise you are making: the caller MUST have actually built
package under the FIPS package set. If you label a non-FIPS build as FIPS,
you’ve shipped a lie — an image that claims validated crypto it doesn’t have.
So the correct sequence is always:
- Build your derivation under the FIPS package set, so it composes a validated
FIPS module:
- Go: BoringCrypto (ADR-0026).
- Rust:
aws-lc-rsin FIPS mode (ADR-0028). - The base crypto libraries follow the FIPS composition (ADR-0002).
- Then pass
fips = trueso the labels tell the truth.
For source-first builds via mkSecureArtifact, fips = true also selects the
FIPS package set for the ecosystem build itself, so the derivation and the
labels stay consistent.
The component asserts it
Because the flag is only a label, the CI component adds a runtime check so a
mislabelled image can’t slip through. When you pass fips: true to the
component, it refuses to go further unless the image genuinely carries the
FIPS label: under slsa-l3, hardened:sign refuses to sign; under slsa-l1,
hardened:build fails before publishing any artifact. Both components run the
same check:
$ nix eval ".#<flake-target>.passthru.labels" --raw \
--apply 'l: l."com.gitlab.image.fips" or "false"'
# anything but "true" (including a failed eval) ⇒ refuse a mislabelled image
This asserts the label is present. It’s the last line of defence, not a substitute for actually building under the FIPS set — a build that isn’t FIPS but is wrongly labelled would still pass the label check. The truthfulness starts with you building under the FIPS package set; the assertion just stops an unlabelled-but-claimed-FIPS image from being signed.
Reference
Go FIPS (BoringCrypto) is ADR-0026, Rust FIPS (aws-lc-rs) is ADR-0028, and the crypto-library FIPS composition is ADR-0002.