diff --git a/README.md b/README.md index 294cc8d..d07adec 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ -# agenix +# agenix - [age](https://github.com/FiloSottile/age)-encrypted secrets for NixOS -[age](https://github.com/FiloSottile/age)-encrypted secrets for NixOS. +`agenix` is a commandline tool for managing secrets encrypted with your existing SSH keys. This project also includes the NixOS module `age` for adding encrypted secrets into the Nix store and decrypting them. -It consists of a NixOS module `age`, and a CLI tool called `agenix` -used for editing and rekeying the secret files. +## Problem and solution + +All files in the Nix store are readable by any system user, so it is not a suitable place for including cleartext secrets. Many existing tools (like NixOps deployment.keys) deploy secrets separately from `nixos-rebuild`, making deployment, caching, and auditing more difficult. Out-of-band secret management is also less reproducible. + +`agenix` solves these issues by using your pre-existing SSH key infrastructure and `age` to encrypt secrets into the Nix store. Secrets are decrypted using an SSH host private key during NixOS system activation. ## Features @@ -22,7 +25,7 @@ Choose one of the following methods: First add it to niv: -```console +```ShellSession $ niv add ryantm/agenix ``` @@ -40,7 +43,7 @@ Then add the following to your configuration.nix in the `imports` list: As root run: -```console +```ShellSession $ nix-channel --add https://github.com/ryantm/agenix/archive/master.tar.gz agenix $ nix-channel --update ``` @@ -108,7 +111,7 @@ $ nix-channel --update You don't need to install it, -```console +```ShellSession nix run github:ryantm/agenix -- --help ``` @@ -120,13 +123,11 @@ but, if you want to (change the system based on your system): } ``` - - ## Tutorial 1. Make a directory to store secrets and `secrets.nix` file for listing secrets and their public keys: - ```console + ```ShellSession $ mkdir secrets $ cd secerts $ touch secrets.nix @@ -135,36 +136,41 @@ but, if you want to (change the system based on your system): ```nix let user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH"; + user2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILI6jSq53F/3hEmSs+oq9L4TwOo1PrDMAgcA1uo1CCV/"; + users = [ user1 user2 ]; + system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE"; + system2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzxQgondgEYcLpcPdJLrTdNgZ2gznOHCAxMdaceTUT1"; + systems = [ system1 system2 ]; in { "secret1.age".publicKeys = [ user1 system1 ]; - "secret2.age".publicKeys = [ user1 ]; + "secret2.age".publicKeys = users ++ systems; } ``` -3. Edit secret files (assuming your SSH private key is in ~/.ssh/): - ```console +3. Edit secret files (these instructions assume your SSH private key is in ~/.ssh/): + ```ShellSession $ agenix -e secret1.age ``` -4. Add secret to NixOS module config: +4. Add secret to a NixOS module config: ```nix age.secrets.secret1.file = ../secrets/secret1.age; ``` -5. NixOS rebuild or use your deployment too like usual. +5. NixOS rebuild or use your deployment tool like usual. ## Rekeying If you change the public keys in `secrets.nix`, you should rekey your secrets: -```console +```ShellSession $ agenix --rekey ``` To rekey a secret, you have to be able to decrypt it. Because of randomness in `age`'s encryption algorithms, the files always change -when rekeyed, even if the identities do not. This eventually could be -improved upon by reading the identities from the age file. +when rekeyed, even if the identities do not. (This eventually could be +improved upon by reading the identities from the age file.) ## Threat model/Warnings @@ -172,17 +178,15 @@ This project has not be audited by a security professional. People unfamiliar with `age` might be surprised that secrets are not authenticated. This means that every attacker that has write access to -the repository can modify secrets because public keys are exposed. +the secret files can modify secrets because public keys are exposed. This seems like not a problem on the first glance because changing the -configuration itself could expose secrets easily. However it is easier -to review configuration changes rather than random secrets (for -example 4096-bit rsa keys). This would be solved by having a message +configuration itself could expose secrets easily. However, reviewing +configuration changes is easier than reviewing random secrets (for +example, 4096-bit rsa keys). This would be solved by having a message authentication code (MAC) like other implementations like GPG or [sops](https://github.com/Mic92/sops-nix) have, however this was left out for simplicity in `age`. ## Acknowledgements -This project is based off of -[sops-nix](https://github.com/Mic92/sops-nix) created Mic92. Thank you -to Mic92 for inspiration and help with making this. +This project is based off of [sops-nix](https://github.com/Mic92/sops-nix) created Mic92. Thank you to Mic92 for inspiration and advice.