git.delta.rocks / jrsonnet / refs/commits / f5a8281dad2c

difftreelog

source

modules/secrets.nix6.5 KiBsourcehistory
1{2  lib,3  config,4  ...5}:6let7  inherit (lib.options) mkOption literalExpression;8  inherit (lib.types)9    unspecified10    nullOr11    listOf12    str13    bool14    attrsOf15    submodule16    functionTo17    package18    uniq19    ;20  inherit (lib.strings) concatStringsSep;21  inherit (lib.attrsets) mapAttrs;2223  sharedSecret =24    { config, ... }:25    {26      options = {27        expectedOwners = mkOption {28          type = nullOr (listOf str);29          description = ''30            Specifies the list of hosts authorized to decrypt and access this shared secret.3132            When null, secret ownership is managed manually via fleet.nix and CLI.33            Decrypted secrets will be stored at /run/secrets/$\{name} on authorized hosts.34          '';35          default = null;36        };37        regenerateOnOwnerAdded = mkOption {38          type = bool;39          description = ''40            Controls whether the secret must be regenerated when new owners are added.4142            Set to true when the secret contains owner-specific references (e.g., X.509 Subject Alternative Names).43            When true, adding a new owner will trigger secret regeneration instead of simple re-encryption.44          '';45        };46        regenerateOnOwnerRemoved = mkOption {47          default = config.regenerateOnOwnerAdded;48          defaultText = literalExpression "regenerateOnOwnerAdded";49          type = bool;50          description = ''51            Determines secret behavior when owners are removed from the configuration.5253            Typically mirrors regenerateOnOwnerAdded. Override cautiously.54            Set to false if host permissions are revoked through alternative mechanisms like firewall rules.55          '';56        };57        generator = mkOption {58          type = uniq (nullOr (functionTo package));59          description = ''60            Function evaluating to nix derivation responsible for (re)generating the secret's content.6162            An input to this function - `pkgs` of a generator host with implementation-defined representation of extra encryption data,63            use `mkSecretGenerator` helpers to implement own generators.64          '';65          default = null;66        };67        expectedGenerationData = mkOption {68          type = unspecified;69          description = "Contextual metadata embedded within the secret part value";70          default = null;71        };72        expectedPrivateParts = mkOption {73          type = listOf str;74          default = [ ];75          description = "List of parts that are expected to be encrypted";76        };77        expectedPublicParts = mkOption {78          type = listOf str;79          default = [ ];80          description = "List of parts that are expected to be public";81        };82      };83    };84in85{86  options = {87    sharedSecrets = mkOption {88      type = attrsOf (submodule sharedSecret);89      default = { };90      description = "Collection of secrets shared across multiple hosts with configurable ownership";91    };92  };93  config = {94    hosts = mapAttrs (95      _: secretMap:96      let97        partsOf =98          s:99          removeAttrs s [100            "createdAt"101            "expiresAt"102            "generationData"103          ];104105      in106      {107        nixos.data.secrets = mapAttrs (_: s: partsOf s) secretMap;108        # nixos.secrets = mapAttrs (109        #   _: s: mapAttrs (_: _: {}) (partsOf s)110        # ) secretMap;111      }112    ) config.data.hostSecrets;113    nixpkgs.overlays = [114      (final: prev: {115        mkSecretGenerators =116          { recipients }:117          rec {118            # TODO: Merge both generators to one with consistent options syntax?119            # Impure generator is built on local machine, then built closure is copied to remote machine,120            # and then it is ran in inpure context, so that this generator may access HSMs and other things.121            mkImpureSecretGenerator =122              {123                script,124                # If set - script will be run on remote machine, otherwise it will be run with fleet project in CWD125                # (Some secrets-encryption-in-git/managed PKI solution is expected)126                impureOn ? null,127              }:128              (prev.writeShellScript "impureGenerator.sh" ''129                #!/bin/sh130                set -eu131132                export GENERATOR_HELPER_IDENTITIES="${concatStringsSep "\n" recipients}";133                export PATH=${final.fleet-generator-helper}/bin:$PATH134135                # TODO: Provide tempdir from outside, to make it securely erasurable as needed?136                tmp=$(mktemp -d)137                cd $tmp138                # cd /var/empty139140                created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")141142                ${script}143144                if ! test -d $out; then145                  echo "impure generator script did not produce expected \$out output"146                  exit 1147                fi148149                echo -n $created_at > $out/created_at150                echo -n SUCCESS > $out/marker151              '').overrideAttrs152                (old: {153                  passthru = {154                    inherit impureOn;155                    generatorKind = "impure";156                  };157                });158            # Pure generators are disabled for now159            mkSecretGenerator = { script }: mkImpureSecretGenerator { inherit script; };160161            # TODO: Implement consistent naming162            # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...163            # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.164            # mkSecretGenerator = {script}:165            #   (prev.writeShellScript "generator.sh" ''166            #     #!/bin/sh167            #     set -eu168            #     # TODO: make nix daemon build secret, not just the script.169            #     cd /var/empty170            #171            #     created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")172            #173            #     ${script}174            #     if ! test -d $out; then175            #       echo "impure generator script did not produce expected \$out output"176            #       exit 1177            #     fi178            #179            #     echo -n $created_at > $out/created_at180            #     echo -n SUCCESS > $out/marker181            #   '')182            #   .overrideAttrs (old: {183            #     passthru = {184            #       generatorKind = "pure";185            #     };186            #     # TODO: make nix daemon build secret, not just the script.187            #     # __impure = true;188            #   });189          };190      })191    ];192  };193}