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

difftreelog

source

nixos/secrets.nix4.3 KiBsourcehistory
1{2  lib,3  config,4  pkgs,5  ...6}: let7  inherit (lib.strings) hasPrefix removePrefix;8  inherit (lib) mkOption mkOptionDefault mapAttrs stringAfter;9  inherit (lib.types) submodule str attrsOf nullOr unspecified lazyAttrsOf;10  plaintextPrefix = "<PLAINTEXT>";11  plaintextNewlinePrefix = "<PLAINTEXT-NL>";1213  sysConfig = config;14  secretPartType = secretName:15    submodule ({config, ...}: {16      options = {17        raw = mkOption {18          description = "Secret in fleet-specific undocumented format, do not use. Import from fleet.nix";19          internal = true;20        };21        hash = mkOption {22          type = str;23          description = "Hash of secret in encoded format";24        };25        path = mkOption {26          type = str;27          description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";28        };29        stablePath = mkOption {30          type = str;31          description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";32        };33        data = mkOption {34          type = str;35          description = "Secret public data (only available for plaintext)";36        };37      };38      config = let39        partName = config._module.args.name;40      in {41        hash = mkOptionDefault (builtins.hashString "sha1" config.raw);42        data = mkOptionDefault (43          if hasPrefix plaintextPrefix config.raw44          then removePrefix plaintextPrefix config.raw45          else if hasPrefix plaintextNewlinePrefix config.raw46          then removePrefix plaintextNewlinePrefix config.raw47          else throw "secret.part.data attribute only works for public plaintext secret parts, got ${config.raw}"48        );49        path = mkOptionDefault "/run/secrets/${secretName}/${config.hash}-${partName}";50        stablePath = mkOptionDefault "/run/secrets/${secretName}/${partName}";51      };52    });53  secretType = submodule ({config, ...}: let54    secretName = config._module.args.name;55  in {56    freeformType = lazyAttrsOf (secretPartType secretName);57    options = {58      shared = mkOption {59        description = "Is this secret owned by this machine, or propagated from shared secrets";60        default = false;61      };62      expectedOwners = mkOption {63        type = nullOr unspecified;64        default = null;65        internal = true;66      };6768      generator = mkOption {69        type = nullOr unspecified;70        description = "Derivation to evaluate for secret generation";71        default = null;72      };73      mode = mkOption {74        type = str;75        description = "Secret mode";76        default = "0440";77      };78      owner = mkOption {79        type = str;80        description = "Owner of the secret";81        default = "root";82      };83      group = mkOption {84        type = str;85        description = "Group of the secret";86        default = sysConfig.users.users.${config.owner}.group;87      };88    };89  });90  processPart = part: {91    inherit (part) raw path stablePath;92  };93  processSecret = secret:94    {95      inherit (secret) group mode owner;96    }97    // (mapAttrs (_: processPart) (removeAttrs secret [98      "shared"99      "generator"100      "mode"101      "group"102      "owner"103104      # FIXME: Some of those removed attributes shouldn't be here, but there is some error in passing shared secrets from fleet to nixos.105      "expectedOwners"106    ]));107  secretsFile = pkgs.writeTextFile {108    name = "secrets.json";109    text =110      builtins.toJSON (mapAttrs (_: processSecret)111        config.secrets);112  };113in {114  options = {115    secrets = mkOption {116      type = attrsOf secretType;117      default = {};118      description = "Host-local secrets";119    };120  };121  config = {122    environment.systemPackages = [pkgs.fleet-install-secrets];123    system.activationScripts.decryptSecrets =124      stringAfter (125        [126          # secrets are owned by user/group, thus we need to refer to those127          "users"128          "groups"129          "specialfs"130        ]131        # nixos-impermanence compatibility: secrets are encrypted by host-key,132        # but with impermanence we expect that the host-key is installed by133        # persist-file activation script.134        ++ (lib.optional (config.system.activationScripts ? "persist-files") "persist-files")135      ) ''136        1>&2 echo "setting up secrets"137        ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}138      '';139  };140}