Trustix - Usage via Nix

The easiest way to use Trustix is via the NixOS modules, though even they require some manual preparation in terms of generating keys.

This document will guide you through the very basic NixOS setup required both by log clients and log publishers.

How to actually publish/subscribe are laid out in other documents.

Requisites

  • A NixOS installation using Flakes

Create keys

All Trustix build logs are first and foremost identified by their key pair, which will be the first thing we have to generate.

Let's start by generating a key pair for our log:

$ mkdir secrets
$ nix run github:nix-community/trustix#trustix -- generate-key --privkey secrets/log-priv --pubkey secrets/log-pub

Additionally logs are identified not just by their key, but how that key is used. If a key is used for multiple protocols (not just Nix) those logs will have a different ID. This ID is what subscribers use to indicate what they want to subscribe to.

To find out the log ID for the key pair you just generated: $ nix run github:nix-community/trustix#trustix -- print-log-id --protocol nix --pubkey $(cat secrets/log-pub)

Flakes

  • flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    trustix = {
      url = "github:nix-community/trustix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { nixpkgs, flake-utils, trustix, ... }: {
    nixosConfigurations.trustix-example = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules =
        [ ({ pkgs, ... }: {
            # import trustix modules
            imports = [
              trustix.nixosModules.trustix
              ./configuration.nix
            ];
          })
        ];
    };

  };
}
  • configuration.nix:
{ config, pkgs, lib, ... }:
{
  services.trustix = {
    enable = true;

    # Trustix differentiates between the concepts of a "signer" and a "publisher".
    # A signer refers to a private key implementation.
    # These can be file based or use hardware tokens.
    signers.my-signer = {
      type = "ed25519";
      # Configuring the private key like this by path is bad practice because the key ends up world readable in /nix/store.
      # You should either:
      # - Put the key in a persistent path and reference it like: `ed25519.private-key-path = "/path/to/key"`
      # - Use a secrets management solution like sops-nix or agenix.
      ed25519.private-key-path = ./secrets/log-priv;
    };

    publishers = [
      {
        # Use the key configured above
        signer = "my-signer";

        # Trustix is built first and foremost for Nix, but could also be used for verifying other package ecosystems.
        protocol = "nix";

        # An arbitrary (string -> string) attrset with metadata about this log.
        # This isn't used by the Trustix logs but is used to inform the Nix binary cache proxy about possible substitution sources.
        meta = {
          upstream = "https://cache.nixos.org";
        };

        # The public key identifying this log.
        publicKey = {
          type = "ed25519";
          key = builtins.readFile ./secrets/log-pub;
        };
      }
    ];
  };
}

Effect

This will set up an instance of Trustix on your system. In the next chapter we will look at using the post build hook to publish results to our local log.