diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 08ef0a4..a309415 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -12,7 +12,7 @@ let # ========== System Public Keys (Age Format) ========== # Convert SSH host keys to age format: # ssh-to-age < secrets/{hostname}/ssh_host_ed25519_key.pub - + # Example (replace with actual age keys): # nix-builder = "age1..."; # usda-dash = "age1..."; @@ -20,7 +20,7 @@ let # ========== User Public Keys (for editing secrets) ========== # These are personal age keys for administrators who need to edit secrets # Generate with: age-keygen - + # Example: # admin1 = "age1..."; # admin2 = "age1..."; diff --git a/sw/secrets.nix b/sw/secrets.nix index d58ce23..70df575 100644 --- a/sw/secrets.nix +++ b/sw/secrets.nix @@ -24,11 +24,7 @@ let hostname = config.networking.hostName; # Read all directories in ./secrets - secretDirs = - if builtins.pathExists secretsPath then - builtins.readDir secretsPath - else - { }; + secretDirs = if builtins.pathExists secretsPath then builtins.readDir secretsPath else { }; # Filter to only directories (excludes files) isDirectory = name: type: type == "directory"; @@ -40,25 +36,23 @@ let let dirPath = secretsPath + "/${dirName}"; files = builtins.readDir dirPath; - + # Check if there's a default.nix with custom secret configurations hasDefaultNix = files ? "default.nix"; customConfigs = if hasDefaultNix then import (dirPath + "/default.nix") else { }; - + # Only include .age files (exclude .pub public keys and other files) - secretFiles = lib.filterAttrs ( - name: type: type == "regular" && lib.hasSuffix ".age" name - ) files; + secretFiles = lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".age" name) files; in lib.mapAttrs' ( name: _: let # Remove .age extension for the secret name secretName = lib.removeSuffix ".age" name; - + # Get custom config for this secret if defined customConfig = customConfigs.${secretName} or { }; - + # Base configuration with file path baseConfig = { file = dirPath + "/${name}"; @@ -74,9 +68,7 @@ let dirPath = secretsPath + "/${dirName}"; files = if builtins.pathExists dirPath then builtins.readDir dirPath else { }; # Only include .pub public key files - pubKeyFiles = lib.filterAttrs ( - name: type: type == "regular" && lib.hasSuffix ".pub" name - ) files; + pubKeyFiles = lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".pub" name) files; in lib.mapAttrsToList ( name: _: @@ -128,7 +120,7 @@ let "/etc/ssh/ssh_host_ed25519_key" "/etc/age/identity.key" ]; - + # Combine all paths and remove duplicates allPaths = lib.unique (defaultPaths ++ globalPaths ++ hostPaths); in @@ -151,29 +143,31 @@ in }; extraSecrets = mkOption { - type = types.attrsOf (types.submodule { - options = { - file = mkOption { - type = types.path; - description = "Path to the encrypted secret file"; + type = types.attrsOf ( + types.submodule { + options = { + file = mkOption { + type = types.path; + description = "Path to the encrypted secret file"; + }; + mode = mkOption { + type = types.str; + default = "0400"; + description = "Permissions mode for the decrypted secret"; + }; + owner = mkOption { + type = types.str; + default = "root"; + description = "Owner of the decrypted secret file"; + }; + group = mkOption { + type = types.str; + default = "root"; + description = "Group of the decrypted secret file"; + }; }; - mode = mkOption { - type = types.str; - default = "0400"; - description = "Permissions mode for the decrypted secret"; - }; - owner = mkOption { - type = types.str; - default = "root"; - description = "Owner of the decrypted secret file"; - }; - group = mkOption { - type = types.str; - default = "root"; - description = "Group of the decrypted secret file"; - }; - }; - }); + } + ); default = { }; description = '' Additional secrets to define manually, beyond the auto-discovered ones. @@ -205,6 +199,8 @@ in let hasSecrets = (builtins.length (builtins.attrNames applicableSecrets)) > 0; in - lib.optional (!hasSecrets) "No age-encrypted secrets found in ./secrets/global/ or ./secrets/${hostname}/"; + lib.optional ( + !hasSecrets + ) "No age-encrypted secrets found in ./secrets/global/ or ./secrets/${hostname}/"; }; }