Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bring your own derivation

Ecosystem detection covers Go, Rust, Python, and Ruby. When your project isn’t one of those — an unsupported ecosystem, a C/C++ build, a mixed build, or anything you’d rather assemble by hand — you skip detection entirely. There are two ways.

Option 1: mkHardenedImage directly

If you already have (or can build) the derivation, this is the simplest path. mkHardenedImage wraps an already-built derivation into a hardened image and attaches its SBOM. It does no detection at all.

let
  myThing = pkgs.stdenv.mkDerivation {
    pname = "my-thing";
    version = "1.0.0";
    src = ./.;
    nativeBuildInputs = [ pkgs.cmake ];
    # …your build…
  };
in
hb.mkHardenedImage {
  name = "my-thing";
  version = "1.0.0";
  package = myThing;
  cmd = [ "/bin/my-thing" ];
}

This is the headline entry point — mkSecureArtifact funnels into it once it has a derivation. If you’re not using the ecosystem dispatch, prefer this over mkSecureArtifact; there’s no reason to route through detection you don’t want.

Option 2: mkSecureArtifact with overrideDerivation

If you’re inside a pipeline that’s already shaped around mkSecureArtifact and you want to keep that shape but bypass detect-and-build for one artifact, pass overrideDerivation. It short-circuits detection and building entirely and images the derivation you hand it:

hb.mkSecureArtifact {
  name = "my-thing";
  version = "1.0.0";
  overrideDerivation = myThing; # skip detect + build, image THIS
  image.cmd = [ "/bin/my-thing" ];
}

When you use overrideDerivation, you don’t need src — the throw that mkSecureArtifact raises for an undetectable src doesn’t fire, because detection is skipped. The result’s passthru.ecosystem is { ecosystem = "custom"; }, a marker that this artifact came from an override rather than a detected ecosystem.

Which one?

They produce the same image and SBOM. Use mkHardenedImage when you’re building images directly, and overrideDerivation only when you want a single uniform mkSecureArtifact call site across a mix of detected and custom artifacts.

Everything else still applies

However you produce the derivation, the rest is unchanged: the CI component signs, attests, and scans it exactly the same way (see Integrate an external project), the SBOM covers its Nix closure (see SBOMs), and fips = true remains a truthfulness contract you must back with a real FIPS build (see FIPS).