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

difftreelog

source

modules/fleet/secrets.nix4.7 KiBsourcehistory
1{ lib, fleetLib, config, ... }: with lib; with fleetLib;2let3  sharedSecret = with types; ({config, ...}: {4    options = {5      expectedOwners = mkOption {6        type = nullOr (listOf str);7        description = ''8          List of hosts to encrypt secret for. null if managed by user (= via owners field from fleet.nix)910          Secrets would be decrypted and stored to /run/secrets/$\{name} on owners11        '';12      };13      # TODO: Aren't those options may be just desugared to data/expectedData?14      regenerateOnOwnerAdded = mkOption {15        type = bool;16        description = ''17          Is this secret owner-dependent, and needs to be regenerated on ownership set change, or it may be just reencrypted.18          19          You want to have this option set to true, when this secret contains some reference to its owners, i.e x509 SANs.20        '';21      };22      regenerateOnOwnerRemoved = mkOption {23        default = config.regenerateOnOwnerAdded;24        type = bool;25        description = ''26          Should this secret be removed on owner removal, or it may be just reencrypted27          28          Most probably its value should be equal to regenerateOnOwnerAdded, override only if you know what are you doing.29          Contrary to regenerateOnOwnerAdded, you may want to set this option to false, when host permissions are revoked30          in some other way than by this secret ownership, I.e by firewall/etc.31        '';32      };33      generator = mkOption {34        type = nullOr unspecified;35        description = "Derivation to evaluate for secret generation";36        default = null;37      };38      createdAt = mkOption {39        type = nullOr str;40        description = "When this secret was (re)generated";41        default = null;42      };43      expiresAt = mkOption {44        type = nullOr str;45        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";46        default = null;47      };4849      owners = mkOption {50        type = listOf str;51        description = ''52          For which owners this secret is currently encrypted,53          if not matches expectedOwners - then this secret is considered outdated, and54          should be regenerated/reencrypted.5556          Imported from fleet.nix57        '';58        default = [ ];59      };60      # TODO: Make secret generator generate arbitrary number of secret/public parts?61      # Make it generate a folder, where all files except suffixed by .enc are public, and the rest are secret?62      # How should modules refer to those files then?63      public = mkOption {64        type = nullOr str;65        description = "Secret public data. Imported from fleet.nix";66        default = null;67      };68      secret = mkOption {69        type = nullOr str;70        description = "Encrypted secret data. Imported from fleet.nix";71        default = null;72        internal = true;73      };74    };75  });76  hostSecret = with types; {77    options = {78      createdAt = mkOption {79        type = nullOr str;80        default = null;81      };82      expiresAt = mkOption {83        type = nullOr str;84        default = null;85      };86      public = mkOption {87        type = nullOr str;88        description = "Secret public data. Imported from fleet.nix";89        default = null;90      };91      secret = mkOption {92        type = nullOr str;93        description = "Encrypted secret data. Imported from fleet.nix";94        default = null;95        internal = true;96      };97    };98  };99in100{101  options = with types; {102    sharedSecrets = mkOption {103      type = attrsOf (submodule sharedSecret);104      default = { };105      description = "Shared secrets";106    };107    hostSecrets = mkOption {108      type = attrsOf (attrsOf (submodule hostSecret));109      default = { };110      description = "Host secrets. Imported from fleet.nix";111      internal = true;112    };113  };114  config = {115    assertions = mapAttrsToList116      (name: secret: {117        assertion = secret.expectedOwners == null || builtins.sort (a: b: a < b) secret.owners == builtins.sort (a: b: a < b) secret.expectedOwners;118        message = "Shared secret ${name} is expected to be encrypted for ${builtins.toJSON secret.expectedOwners}, but it is encrypted for ${builtins.toJSON secret.owners}. Run fleet secrets regenerate to fix";119      })120      config.sharedSecrets;121    hosts = hostsToAttrs (host: {122      modules =123        let124          cleanupSecret = (secretName: v: {125            inherit (v) public secret;126            shared = true;127          });128        in129        [130          {131            secrets = (mapAttrs cleanupSecret132              (filterAttrs (_: v: builtins.elem host v.owners) config.sharedSecrets)133            ) // (mapAttrs cleanupSecret (config.hostSecrets.${host} or { }));134          }135        ];136    });137  };138}