Integrate with NixOS

This guide shows how to integrate nixos-artifacts-agenix into your NixOS configuration for machine-level secrets.

Module Setup

Add the required inputs and import the modules:

{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  inputs.nixos-artifacts.url = "github:mrVanDalo/nixos-artifacts"; (1)
  inputs.nixos-artifacts-agenix.url = "github:mrVanDalo/nixos-artifacts-agenix"; (2)

  outputs = inputs@{ self, nixpkgs, ... }: {
    nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        inputs.nixos-artifacts.nixosModules.default (3)
        inputs.nixos-artifacts-agenix.nixosModules.default (4)
        # Your host configuration:
        ({ config, pkgs, ... }: {
          networking.hostName = "my-host";
          artifacts.default.backend.serialization = "agenix"; (5)

          # Configure the agenix backend
          artifacts.config.agenix = {
            flakeStoreDir = ./secrets;  (6)
            publicHostKey = "ssh-ed25519 AAAA...host..."; (7)
            publicUserKeys = [ (8)
              "ssh-ed25519 AAAA...user1..."
              "ssh-ed25519 AAAA...user2..."
            ];
          };
        })
      ];
    };
  };
}
1 Core artifacts framework
2 Agenix backend for artifacts
3 Core artifacts options
4 Agenix backend options (includes agenix.nixosModules.default)
5 Set agenix as the serialization backend
6 Path reference where encrypted secrets are stored
7 Public key used to encrypt secrets for this host
8 Additional public keys able to decrypt the secrets
storeDir defaults to "secrets", which matches flakeStoreDir = ./secrets. Override it only if the TUI must write to a different working directory; in that case keep both options pointing at the same location, otherwise agenix will not find the encrypted files at runtime.

Module Variants

Two module variants are available:

nixosModules.default

Includes the agenix NixOS module. Use this for standard setups.

nixosModules.without-agenix

Only provides nixos-artifacts integration. Use this if you already have agenix configured elsewhere in your configuration.

Accessing Secrets at Runtime

After deserialization, secrets can be accessed in two ways:

Via nixos-artifacts

Use the artifacts path reference directly:

{ config, ... }:
{
  services.my-service = {
    passwordFile = config.artifacts.store.my-secret.files.password.path;
  };
}

Via agenix

Since the agenix module is included, you can also use the standard agenix options. Each file in an artifact is exposed under age.secrets.<artifact-name>-<file-name>:

{ config, ... }:
{
  services.my-service = {
    # Artifact `my-secret` with file `password` becomes `my-secret-password`
    passwordFile = config.age.secrets.my-secret-password.path;
  };
}

Both approaches work because nixos-artifacts-agenix maps artifacts.store to age.secrets behind the scenes. Use whichever fits your preference - the artifacts abstraction provides consistency, while the agenix options give you access to all agenix-specific features like owner, mode, and group.

Key Differences from Home Manager Integration

Aspect NixOS Home Manager

Directory

secrets/per-machine/<hostname>/

secrets/per-user/<username>/

Encryption keys

publicHostKey + publicUserKeys

publicUserKeys only

Decryption

Automatic (host SSH keys)

Requires identityPaths

Use case

System services, root configs

User applications, dotfiles