3 min read
Managing Secrets in a Public Nix Repository with Agenix

When you manage your system configurations with Nix in a public Git repository, one of the first challenges you’ll face is how to handle secrets. You can’t just commit your API keys, passwords, and other sensitive data directly into your repository. This is where a tool like agenix comes in.

agenix is a simple, modern, and secure secret management tool for NixOS that uses age for encryption. It allows you to encrypt your secrets and safely commit them to your public repository. In this post, we’ll explore how to set up and use agenix in a Nix Flake.

The agenix Setup

First, you need to add agenix as an input to your flake.nix:

{
  inputs = {
    # ... other inputs
    agenix = {
      url = "github:ryantm/agenix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  // ...
}

Next, you need to enable the agenix module in your NixOS or nix-darwin configuration. This is done by adding agenix.nixosModules.default or agenix.darwinModules.default to your list of modules.

Defining Secrets

With agenix enabled, you can now define your secrets. The secrets are defined in a secrets.nix file, which specifies the public keys that can decrypt each secret.

Here’s an example of a secrets.nix file:

let
  user1 = "ssh-rsa AAAA... user1@example.com";
  user2 = "ssh-rsa AAAA... user2@example.com";

  keys = [ user1 user2 ];
in
{
  "vpnCredentials.age".publicKeys = keys;
  "secretService.age".publicKeys = keys;
  # ... other secrets
}

In this file, we define the public SSH keys for the users and systems that are allowed to decrypt the secrets. Then, for each secret, we specify which keys can decrypt it.

Encrypting and Decrypting Secrets

To encrypt a secret, you can use the agenix command-line tool:

echo -n "my-secret-value" | agenix -e -i /path/to/identity.key /path/to/secret.age

This will create an encrypted file at /path/to/secret.age. You can then commit this file to your repository.

When you run nixos-rebuild switch, agenix will automatically decrypt the secrets and make them available to your NixOS configuration. You can then use the secrets in your modules, for example, to set the password for a service.

Conclusion

agenix provides a simple and secure way to manage secrets in a public Nix repository. By using age for encryption and integrating with NixOS and nix-darwin, it allows you to keep your secrets safe while still enjoying the benefits of a declarative and reproducible system configuration.