git.delta.rocks / jrsonnet / refs/commits / 3e7b063c34a7

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  };5657  hostSecretData = {58    freeformType = attrsOf (submodule secretDataValue);59    options = {60      createdAt = mkOption {61        type = str;62        description = "When this secret was (re)generated";63        default = null;64      };65      expiresAt = mkOption {66        type = nullOr str;67        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";68        default = null;69      };70      shared = mkOption {71        type = bool;72        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";73        default = false;74      };75      generationData = mkOption {76        type = unspecified;77        description = "Data that is embedded into secret part";78        default = null;79      };80    };81  };82in {83  options.data = mkDataOption ({config, ...}: {84    options = {85      sharedSecrets = mkOption {86        type = attrsOf (submodule sharedSecretData);87        default = {};88        description = "Stored shared secret data.";89      };90      hostSecrets = mkOption {91        type = attrsOf (attrsOf (submodule hostSecretData));92        default = {};93        description = "Host secrets.";94        internal = true;95      };96    };97    config.hostSecrets = let98      hostsWithSharedSecrets = unique (concatLists (mapAttrsToList (_: s: s.owners) config.sharedSecrets));99      secretsHavingHost = host: filterAttrs (_: secret: lib.elem host secret.owners) config.sharedSecrets;100      toHostSecret = _: secret: (removeAttrs secret ["owners"]) // {shared = true;};101    in102      genAttrs hostsWithSharedSecrets (host: mapAttrs toHostSecret (secretsHavingHost host));103  });104  config = {105    assertions =106      (mapAttrsToList107        (name: secret: {108          assertion = secret.expectedOwners == null || sort (a: b: a < b) config.data.sharedSecrets.${name}.owners == sort (a: b: a < b) secret.expectedOwners;109          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";110        })111        config.sharedSecrets)112      ++ (mapAttrsToList113        (name: secret: {114          # TODO: Same aassertion should be in host secrets115          assertion = config.data.sharedSecrets.${name}.generationData == secret.expectedGenerationData;116          message = "Shared secret ${name} has unexpected generation data ${toJSON secret.expectedGenerationData} != ${toJSON config.data.sharedSecrets.${name}.expectedGenerationData}. Run fleet secrets regenerate to fix";117        })118        config.sharedSecrets);119    sharedSecrets =120      mapAttrs (_: _: {}) config.data.sharedSecrets;121  };122}