oddlama / agenix-rekey

An agenix extension adding secret generation and automatic rekeying using a YubiKey or master-identity
MIT License
213 stars 18 forks source link

[Question] How do I use this to encrypt/decrypt agenix secrets with a Yubikey age key? #10

Closed NovaViper closed 8 months ago

NovaViper commented 11 months ago

Hey I'm wondering if it possible to use this to circumvent this issue where it's not possible to natively decrypt agenix secrets with a age key that lives on a Yubikey. I basically want to have one key that decrypts the secrets for my users and each key will be for that specific user (since I have one atm, it will just be that one key in the flake). The goal is to allow my flake to encrypt new secrets to my flake and then allow me to decrypt them whenever I need to say for instance, reinstall NixOS onto my computer.

oddlama commented 11 months ago

I'm not entirely sure whether I understand your question. What do you mean with "natively decrypt"? Are you referring to using a YubiKey on boot when the agenix secrets are decrypted, or do you want to use the YubiKey when building your NixOS (providing rekeyed secrets to your host that can be decrypted by that host automatically)?

The way agenix-rekey works is the following:

I believe this would be a solution to the issue you linked, although you will probably run into issues when using multiple yubikeys. I'm not sure what the benefit of using multiple yubikeys would be here, since you will require all yubikeys anyways when rekeying secrets.

NovaViper commented 11 months ago

What do you mean with "natively decrypt"?

Ah my bad, I should've clarified this part more. What I meant was agenix doesn't actually support decrypting secrets with Yubikey-based age keys at all; since agenix expects you to have identity files (which are generated when you create the age keys on the computer; this case isn't true for age keys that's made on the Yubikey).

Are you referring to using a YubiKey on boot when the agenix secrets are decrypted, or do you want to use the YubiKey when building your NixOS (providing rekeyed secrets to your host that can be decrypted by that host automatically)?

I want to be able to use the Yubikey when I'm building my NixOS config like in the second case you described

I believe this would be a solution to the issue you linked, although you will probably run into issues when using multiple yubikeys. I'm not sure what the benefit of using multiple yubikeys would be here, since you will require all yubikeys anyways when rekeying secrets.

I wouldn't actually be using multiple seperate Yubikeys per say, more like different age keys that's generated on the same Yubikey (and having an actual backup Yubikey that I can fallback to in case the main one gets damaged somehow). 🤔 I'm unsure how the backup Yubikey would work though since like you said, I would have to have both Yubikeys in the system in order to rekey the secrets

oddlama commented 11 months ago

Ah my bad, I should've clarified this part more. What I meant was agenix doesn't actually support decrypting secrets with Yubikey-based age keys at all; since agenix expects you to have identity files (which are generated when you create the age keys on the computer; this case isn't true for age keys that's made on the Yubikey).

Ah I see. This utility replaces the need for the original agenix command and ours works differently. If you run agenix edit hosts/myhost/mysecret.age, you will be prompted to decrypt it with your yubikey.

I want to be able to use the Yubikey when I'm building my NixOS config like in the second case you described

Then this project should work for you, this is exactly what it was made for :)

I wouldn't actually be using multiple seperate Yubikeys per say, more like different age keys that's generated on the same Yubikey (and having an actual backup Yubikey that I can fallback to in case the main one gets damaged somehow). 🤔 I'm unsure how the backup Yubikey would work though since like you said, I would have to have both Yubikeys in the system in order to rekey the secrets

Adding a backup key is easy, I've included an option called extraEncryptionPubkeys where you can specify any age public key (either yubikey keygrab or regular public identity), which will cause any files edited via agenix edit to also be encrypted to those identities. I also have a backup yubikey lying around that I could use to decrypt all of my secrets this way.

I still don't understand why you'd want to use different age identities in different slots on the same yubikey though. Technically nothing prevents you from specifying multiple masterIdentities, one for each slot. But currently this will cause all secrets to be encrypted for all master identities since there's no secret-level-granularity to specifying identities, because there's no real benefit to doing so that I can see. What is your usecase?

Although there are some usability caveats to specifying multiple master identities: If you add multiple master identities, age-plugin-yubikey will always try to decrypt the given file with the first identity. Only when you actively press skip, it will try the next one. There is no autodetection that would automatically select the correct yubikey based on which key is plugged in.

NovaViper commented 11 months ago

Perfect! I'm going to start getting the config all set for it and give it a go. Thank you!

I still don't understand why you'd want to use different age identities in different slots on the same yubikey though. Technically nothing prevents you from specifying multiple masterIdentities, one for each slot. But currently this will cause all secrets to be encrypted for all master identities since there's no secret-level-granularity to specifying identities, because there's no real benefit to doing so that I can see. What is your usecase?

This more is just a proposed idea, in case I ever want to add multiple users. This more came from how this repo implements secrets with sops-nix. But thinking about it again, just sticking with one master identity like you said would be simpler to manage

NovaViper commented 11 months ago

Hey quick question, so I started adding agenix to my config but I got a couple of questions:

{ environment.systemPackages = with pkgs; [ inputs.agenix-rekey.packages.${system}.default ]; }


flake.nix

... outputs = { self, nixpkgs, home-manager, agenix-rekey, ... }@inputs: let inherit (self) outputs; lib = nixpkgs.lib // home-manager.lib;

Supported systems for your flake packages, shell, etc.

  systems = [
    "aarch64-linux"
    "i686-linux"
    "x86_64-linux"
    "aarch64-darwin"
    "x86_64-darwin"
  ];
  # This is a function that generates an attribute by calling a function you pass to it, with each system as an argument
  forEachSystem = f: lib.genAttrs systems (system: f pkgsFor.${system});
  pkgsFor = lib.genAttrs systems (system:
    import nixpkgs {
      inherit system;
      config.allowUnfree = true;
    });
in {
  inherit lib;
  # Reusable nixos modules you might want to export
  # These are usually stuff you would upstream into nixpkgs
  nixosModules = import ./modules/nixos;
  # Reusable home-manager modules you might want to export
  # These are usually stuff you would upstream into home-manager
  homeManagerModules = import ./modules/home-manager;
  #templates = import ./templates;

  # Your custom packages and modifications, exported as overlays
  overlays = import ./overlays { inherit inputs outputs; };

  # Your custom packages
  # Acessible through 'nix build', 'nix shell', etc
  packages = forEachSystem (pkgs: import ./pkgs { inherit pkgs; });
  # Devshell for bootstrapping
  # Acessible through 'nix develop' or 'nix-shell' (legacy)
  devShells = forEachSystem (pkgs: import ./shell.nix { inherit pkgs; });
  # Formatter for your nix files, available through 'nix fmt'
  # Other options beside 'alejandra' include 'nixpkgs-fmt'
  formatter = forEachSystem (pkgs: pkgs.nixpkgs-fmt);

  agenix-rekey = agenix-rekey.configure {
    userFlake = self;
    inherit (self) nodes pkgs;
  };

...

oddlama commented 11 months ago
  • Is it possible to use the plugin and agenix with Home-Manager? I do have a couple of secrets that's located under the home folder for the user

There is no module for HM currently, but nothing prevents you from using the secrets defined on the underlying nixos host in home manager. So deploying a pure HM config without an underlying nixos is currently not possible.

  • How do I add agenix-rekey to be installed on the dev shell and on the system (without having to use nix run to access the command)? As the per the current instructions, it assumes that I'm using flake-utils (which I'm currently not) my dev-shell looks like this

It doesn't assume you are using flake-utils. The example just uses it, but you are free to not use it. There is nothing dependent on it in there, it's just syntactical sugar. I would also advise against adding it to your system packages, since you want to make sure to use the agenix-rekey utility from the same version as the one in your flake. Otherwise you will run into issues where your system utility is one or more versions behind the rest of the code pulled in by your flake. So always add it to your devshell, and only use it from there to make sure the agenix rekey command uses the same sources as the system you are building.

What you are missing in your setup is adding it to your overlays (see code example in Installation section), so for given your code you want to add the following:

[...]
        import nixpkgs {
          inherit system;
          config.allowUnfree = true;
          overlays = [ agenix-rekey.overlays.default ]; # <-- this
        });   
[...]
oddlama commented 8 months ago

I'm closing this since I believe the original question was answered. If you need anything else, let me know.