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

difftreelog

source

modules/secrets-data.nix4.2 KiBsourcehistory
1{2  lib,3  fleetLib,4  config,5  ...6}: let7  inherit (fleetLib.options) mkDataOption;8  inherit (lib.options) mkOption;9  inherit (lib.types) nullOr listOf str attrsOf submodule bool unspecified;10  inherit (lib.attrsets) mapAttrsToList mapAttrs filterAttrs genAttrs;11  inherit (lib.lists) sort unique concatLists;12  inherit (lib.strings) toJSON;1314  secretDataValue = {15    options = {16      raw = mkOption {17        type = nullOr str;18        description = "Encrypted + encoded secret data";19        default = null;20      };21    };22  };2324  sharedSecretData = {25    freeformType = attrsOf (submodule secretDataValue);26    options = {27      createdAt = mkOption {28        type = str;29        description = "When this secret was (re)generated";30        default = null;31      };32      expiresAt = mkOption {33        type = nullOr str;34        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";35        default = null;36      };3738      owners = mkOption {39        type = listOf str;40        description = ''41          For which owners this secret is currently encrypted,42          if not matches expectedOwners - then this secret is considered outdated, and43          should be regenerated/reencrypted.4445          Imported from fleet.nix46        '';47        default = [];48      };49      generationData = mkOption {50        type = unspecified;51        description = "Data that is embedded into secret part";52        default = null;53      };54    };55    config = {};56  };5758  hostSecretData = {59    freeformType = attrsOf (submodule secretDataValue);60    options = {61      createdAt = mkOption {62        type = str;63        description = "When this secret was (re)generated";64        default = null;65      };66      expiresAt = mkOption {67        type = nullOr str;68        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";69        default = null;70      };71      shared = mkOption {72        type = bool;73        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";74        default = false;75      };76      generationData = mkOption {77        type = unspecified;78        description = "Data that is embedded into secret part";79        default = null;80      };81    };82    config = {};83  };84in {85  options.data = mkDataOption ({config, ...}: {86    options = {87      sharedSecrets = mkOption {88        type = attrsOf (submodule sharedSecretData);89        default = {};90        description = "Stored shared secret data.";91      };92      hostSecrets = mkOption {93        type = attrsOf (attrsOf (submodule hostSecretData));94        default = {};95        description = "Host secrets.";96        internal = true;97      };98    };99    config.hostSecrets = let100      hostsWithSharedSecrets = unique (concatLists (mapAttrsToList (_: s: s.owners) config.sharedSecrets));101      secretsHavingHost = host: filterAttrs (_: secret: lib.elem host secret.owners) config.sharedSecrets;102      toHostSecret = _: secret: (removeAttrs secret ["owners"]) // {shared = true;};103    in104      genAttrs hostsWithSharedSecrets (host: mapAttrs toHostSecret (secretsHavingHost host));105  });106  config = {107    assertions =108      (mapAttrsToList109        (name: secret: {110          assertion = secret.expectedOwners == null || sort (a: b: a < b) config.data.sharedSecrets.${name}.owners == sort (a: b: a < b) secret.expectedOwners;111          message = "Shared secret ${name} is expected to be encrypted for ${toJSON secret.expectedOwners}, but it is encrypted for ${toJSON config.data.sharedSecrets.${name}.owners}. Run fleet secrets regenerate to fix";112        })113        config.sharedSecrets)114      ++ (mapAttrsToList115        (name: secret: {116          # TODO: Same aassertion should be in host secrets117          assertion = config.data.sharedSecrets.${name}.generationData == secret.expectedGenerationData;118          message = "Shared secret ${name} has unexpected generation data ${toJSON secret.expectedGenerationData} != ${toJSON config.data.sharedSecrets.${name}.expectedGenerationData}. Run fleet secrets regenerate to fix";119        })120        config.sharedSecrets);121    sharedSecrets =122      mapAttrs (_: _: {}) config.data.sharedSecrets;123  };124}