git.delta.rocks / jrsonnet / refs/heads / trunk

difftreelog

source

modules/secrets.nix6.2 KiBsourcehistory
1{2  lib,3  config,4  ...5}:6let7  inherit (lib.options) mkOption;8  inherit (lib.types)9    nullOr10    listOf11    str12    bool13    attrsOf14    submodule15    functionTo16    package17    uniq18    ;19  inherit (lib.strings) concatStringsSep;20  inherit (lib.lists) elem filter;21  inherit (lib.attrsets) attrNames;2223  sharedSecret =24    { config, ... }:25    {26      options = {27        expectedOwners = mkOption {28          type = listOf str;29          description = ''30            Specifies the list of hosts authorized to decrypt and access this shared secret.31          '';32        };33        regenerateOnOwnerAdded = mkOption {34          type = bool;35          description = ''36            Whether the secret prefers to be rotated when new owners are added.3738            Note that this is only a security measure, if the secret needs to be regenerated due to e.g X.509 SANs39            changes - then you most likely want to use generationData for that instead.40          '';41          default = false;42        };43        regenerateOnOwnerRemoved = mkOption {44          type = bool;45          description = ''46            Whether the secret prefers to be rotated when the owners are removed, so the encrypted data47            stored in fleet state can't be decrypted by those. Note that the secrets are still present in encrypted48            form on those hosts until gc happens.49          '';50          default = false;51        };52        allowDifferent = mkOption {53          type = bool;54          description = ''55            When adding owner, do not update secret value for other owners, instead creating a new distribution.5657            Defaults to true, since all secrets might differ on hosts on some point of deployment process.5859            Secret generator might also have opinion on this, like it makes little sense for askPass/synchronizing60            generators to keep old data.61          '';62          default = true;63        };64        generator = mkOption {65          type = uniq (nullOr (functionTo package));66          description = ''67            Function evaluating to nix derivation responsible for (re)generating the secret's content.6869            An input to this function - `pkgs` of a generator host with implementation-defined representation of extra encryption data,70            use `mkSecretGenerator` helpers to implement own generators.71          '';72          default = null;73        };74      };75    };76in77{78  options = {79    secrets = mkOption {80      type = attrsOf (submodule sharedSecret);81      default = { };82      description = "Collection of secrets shared across multiple hosts with configurable ownership";83    };84  };85  config = {86    nixos =87      { host, ... }:88      {89        _providedSharedSecrets = filter (name: elem host.name config.secrets.${name}.expectedOwners) (90          attrNames config.secrets91        );92      };93    nixpkgs.overlays = [94      (final: prev: {95        mkSecretGenerators =96          { recipients }:97          rec {98            # TODO: Merge both generators to one with consistent options syntax?99            # Impure generator is built on local machine, then built closure is copied to remote machine,100            # and then it is ran in inpure context, so that this generator may access HSMs and other things.101            mkImpureSecretGenerator =102              {103                script,104                # If set - script will be run on remote machine, otherwise it will be run with fleet project in CWD105                # (Some secrets-encryption-in-git/managed PKI solution is expected)106                impureOn ? null,107                generationData ? null,108                allowDifferent ? true,109                parts,110              }:111              (prev.writeShellScript "impureGenerator.sh" ''112                #!/bin/sh113                set -eu114115                export GENERATOR_HELPER_IDENTITIES="${concatStringsSep "\n" recipients}";116                export PATH=${final.fleet-generator-helper}/bin:$PATH117118                # TODO: Provide tempdir from outside, to make it securely erasurable as needed?119                tmp=$(mktemp -d)120                cd $tmp121                # cd /var/empty122123                created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")124125                ${script}126127                if ! test -d $out; then128                  echo "impure generator script did not produce expected \$out output"129                  exit 1130                fi131132                echo -n $created_at > $out/created_at133                echo -n SUCCESS > $out/marker134              '').overrideAttrs135                (old: {136                  passthru = {137                    inherit138                      impureOn139                      parts140                      generationData141                      allowDifferent142                      ;143                    generatorKind = "impure";144                  };145                });146            # Pure generators are disabled for now147            mkSecretGenerator = { script, parts }: mkImpureSecretGenerator { inherit script parts; };148149            # TODO: Implement consistent naming150            # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...151            # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.152            # mkSecretGenerator = {script}:153            #   (prev.writeShellScript "generator.sh" ''154            #     #!/bin/sh155            #     set -eu156            #     # TODO: make nix daemon build secret, not just the script.157            #     cd /var/empty158            #159            #     created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")160            #161            #     ${script}162            #     if ! test -d $out; then163            #       echo "impure generator script did not produce expected \$out output"164            #       exit 1165            #     fi166            #167            #     echo -n $created_at > $out/created_at168            #     echo -n SUCCESS > $out/marker169            #   '')170            #   .overrideAttrs (old: {171            #     passthru = {172            #       generatorKind = "pure";173            #     };174            #     # TODO: make nix daemon build secret, not just the script.175            #     # __impure = true;176            #   });177          };178      })179    ];180  };181}