aciceri / agenix-shell

https://flake.parts/options/agenix-shell
35 stars 3 forks source link

agenix-shell

Leveraging age and agenix this project gives you the ability to inject variables containing secrets into your flakes' devShells.

This simplify a lot the onboarding phase for new developers allowing them to share secrets (it's possible to set who can access which secrets) and make projects more self-contained eliminating the need of external tools.

Usage

Minimal knowledge of how agenix operates is required, indeed it relies on having the same setup as agenix i.e. a secrets directory containing all the encrypted secrets and a secrets.nix file that lists them and specifies which keys can be used to decrypt each secret.

Example of secrets/secrets.nix file:

{
  "foo.age".publicKeys = [
    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDpVA+jisOuuNDeCJ67M11qUP8YY29cipajWzTFAobi"
  ];
}

Notice how while this is the format expected by agenix script you are not required to use the same since agenix-shell will require you to set the paths for the .age files (exactly as the agenix modules do).

agenix-shell will inject two environment variables for each secret, one containing the cleartext secret itself and the other one containing the path to the secret. Assuming the example above you will get:

Basic usage

{
  devShells.${system}.default = let
    installationScript = inputs.agenix-shell.packages.${system}.installationScript.override {
      agenixShellConfig.secrets = {
        foo.file = ./secrets/foo.age;
      };
    };
  in pkgs.mkShell {
    shellHook = ''
      source ${lib.getExe installationScript}
    '';
  };
}

Check the basic example for a working example (you will need to delete the encrypted secret and encrypt your own with your key). Otherwise you could copy the used key.

nix flake init -t github:aciceri/agenix-shell#basic

Notice that internally this approach uses flake-parts for reading agenixShellConfig, so you can browse the automatically generated documentation on flake.parts for understanding all the options available that you can pass in agenixShellConfig.

With flake-parts

{
  imports = [
    inputs.agenix-shell.flakeModules.default
  ];

  agenix-shell = {
    secrets = {
      foo.file = ./secrets/foo.age;
    };
  };

  perSystem = {pkgs, config, lib, ... }: {
    devShells.default = pkgs.mkShell {
      shellHook = ''
        source ${lib.getExe config.agenix-shell.installationScript}
      '';
    };
  };
}

Check the flake-parts template for a working example (you will need to delete the encrypted secret and encrypt your own with your key). Otherwise you could copy the used key.

nix flake init -t github:aciceri/agenix-shell#flake-parts 

With devenv

Here a working template.

nix flake init -t github:aciceri/agenix-shell#devenv

How it works

The functioning is quite simple, agenix-shell exports a configurable script that will be sourced somewhere in the devShell (like in an hook). This script will:

That's it! Everything is as customizable as possible using the appropriate options. Check flake.parts for a complete list (and to know defaults).

Things to do