1{ lib, fleetLib, config, ... }: with lib; with fleetLib;2let3 sharedSecret = with types; {4 options = {5 owners = mkOption {6 type = listOf str;7 description = ''8 For which owners this secret is currently encrypted,9 if not matches expectedOwners - then this secret is considered outdated, and10 should be regenerated/reencrypted11 '';12 default = [ ];13 };14 expectedOwners = mkOption {15 type = listOf str;16 description = ''17 List of hosts to encrypt secret for1819 Secrets would be decrypted and stored to /run/secrets/$\{name} on owners20 '';21 default = [ ];22 };23 ownerDependent = mkOption {24 type = bool;25 description = "Is this secret owner-dependent, and needs to be regenerated on ownership set change, or it may be just reencrypted";26 };27 generator = mkOption {28 type = nullOr package;29 description = ''30 Derivation to execute for secret generation3132 If null - may only be created manually33 '';34 default = null;35 };36 expireIn = mkOption {37 type = nullOr int;38 description = "Time in hours, in which this secret should be regenerated";39 default = null;40 };41 public = mkOption {42 type = nullOr str;43 description = "Secret public data";44 default = null;45 };46 secret = mkOption {47 type = nullOr str;48 description = "Encrypted secret data";49 default = null;50 };51 };52 };53 hostSecret = with types; {54 options = {55 generator = mkOption {56 type = package;57 description = "Derivation to execute for secret generation";58 };59 expireIn = mkOption {60 type = nullOr int;61 description = "Time in hours, in which this secret should be regenerated";62 default = null;63 };64 public = mkOption {65 type = nullOr str;66 description = "Secret public data";67 default = null;68 };69 secret = mkOption {70 type = str;71 description = "Encrypted secret data";72 };73 };74 };75in76{77 options = with types; {78 sharedSecrets = mkOption {79 type = attrsOf (submodule sharedSecret);80 default = { };81 description = "Shared secrets";82 };83 hostSecrets = mkOption {84 type = attrsOf (attrsOf (submodule hostSecret));85 default = { };86 description = "Host secrets";87 };88 };89 config = {90 assertions = mapAttrsToList91 (name: secret: {92 assertion = builtins.sort (a: b: a < b) secret.owners == builtins.sort (a: b: a < b) secret.expectedOwners;93 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";94 })95 config.sharedSecrets;96 hosts = hostsToAttrs (host: {97 modules =98 let99 cleanupSecret = (secretName: v: {100 inherit (v) public secret;101 });102 in103 [104 {105 secrets = (mapAttrs cleanupSecret106 (filterAttrs (_: v: builtins.elem host v.owners) config.sharedSecrets)107 ) // (mapAttrs cleanupSecret (config.hostSecrets.${host} or { }));108 }109 ];110 });111 };112}