GitLab Hardened Builds
This project builds GitLab’s components from source, hermetically, with Nix — and attaches the supply-chain evidence that a secure release needs: a complete SBOM, SLSA provenance, Sigstore signatures, vulnerability scans with VEX exceptions, and (where it applies) FIPS-validated crypto.
You don’t have to be GitLab-the-monorepo to use it. If you have a
gitlab-org/* project, you can hand this project a derivation — or just your
source tree — and get back a hardened, signed, attested OCI image with a signed
SBOM.
What you get
- A hardened image. No shell in production images, non-root by default,
minimal layers, standard OCI labels — built with the same
buildGitlabImagebuilder GitLab’s own service images use. - A complete SBOM. CycloneDX, covering the Nix runtime closure and the language-ecosystem dependencies (Go modules, Rust crates, Ruby gems, Python wheels, npm/yarn packages) that a closure-only walk misses.
- Signatures and provenance. Keyless Sigstore signatures over the artifact, the SBOM, and a SLSA v1.0 provenance statement.
- A vulnerability gate. Grype against the SBOM, with OpenVEX exceptions so a known-not-affected CVE doesn’t block your release.
- SLSA Level 3 isolation. The from-source build runs on an ephemeral, offline VM with no secrets and no network — the same tier this project builds its own artifacts on.
- FIPS, optionally. Build under the FIPS package set and your image carries truthful FIPS labels backed by a validated module.
The two halves
The system splits cleanly, and it’s worth understanding why:
-
A pure-Nix API you import from this flake (
lib.${system}.mkHardenedImage/mkSecureArtifact). It produces the image and the SBOM. It’s deterministic, IFD-free, and needs no secrets — so it runs anywhere yournix buildruns. -
A reusable CI component you
includein your pipeline. It does the parts that can’t be a pure function: signing, attestation, the offline SLSA L3 build, and the scan gate. Those need this project’s signing key, its Sigstore identity, and its offline runners — so they live in CI, not in a Nix function you import.
This split is deliberate. An imported Nix function can’t hold a signing key or run an offline VM, so it doesn’t pretend to. See Signing & provenance and SLSA Level 3 builds for the details.
Where to start
- New here? Read the Quickstart.
- Need to check a term’s definition? See the Glossary
- Integrating a whole project’s pipeline? See Integrate an external project.
- Want the function signatures? The API reference is generated from the source doc-comments.
- Looking for the live build evidence for a release? When the pipeline has build-matrix results, the Build matrix chapter (listed after the API reference) shows every image’s SBOM, signature, provenance, findings, and applied overrides.
This documentation describes the API defined in ADR-0039 and the requirements FR-091..FR-104 in the implementation spec. Where a capability is still being wired, the relevant page says so plainly rather than implying it’s finished.