From 7c07727150444ad74199767f186b808f0f211232 Mon Sep 17 00:00:00 2001 From: UGA Innovation Factory Date: Fri, 30 Jan 2026 23:19:38 +0000 Subject: [PATCH] feat: USDA-dash now uses encrypted .env files --- fleet/fs.nix | 66 +++++++++++++++++++++++---------------------- secrets.nix | 46 +++++++++++-------------------- secrets/secrets.nix | 17 ------------ sw/secrets.nix | 5 +++- 4 files changed, 53 insertions(+), 81 deletions(-) diff --git a/fleet/fs.nix b/fleet/fs.nix index b1a2098..3c5acb3 100644 --- a/fleet/fs.nix +++ b/fleet/fs.nix @@ -27,42 +27,44 @@ in }; filesystem = { device = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = '' - The main disk device to use for automated partitioning and installation. + type = lib.types.nullOr lib.types.str; + default = null; + description = '' + The main disk device to use for automated partitioning and installation. - When set, enables disko for declarative disk management with: - - 1GB EFI boot partition - - Optional swap partition (see swapSize) - - Root partition using remaining space + When set, enables disko for declarative disk management with: + - 1GB EFI boot partition + - Optional swap partition (see swapSize) + - Root partition using remaining space - Leave null for systems that don't need disk partitioning (containers, WSL). - ''; - example = "/dev/nvme0n1"; - }; - useSwap = lib.mkOption { - type = lib.types.bool; - default = true; - description = '' - Whether to create and use a swap partition. - Disable for systems with ample RAM or SSDs where swap is undesirable. - ''; - }; - swapSize = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = '' - Size of the swap partition (e.g., "16G", "32G"). + Leave null for systems that don't need disk partitioning (containers, WSL). + ''; + example = "/dev/nvme0n1"; + }; + useSwap = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Whether to create and use a swap partition. + Disable for systems with ample RAM or SSDs where swap is undesirable. + ''; + }; + swapSize = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = '' + Size of the swap partition (e.g., "16G", "32G"). - Recommended sizes: - - 8-16GB for desktops with 16GB+ RAM - - 32GB for laptops (enables hibernation) - - Match RAM size for systems <8GB RAM - ''; - example = "32G"; + Recommended sizes: + - 8-16GB for desktops with 16GB+ RAM + - 32GB for laptops (enables hibernation) + - Match RAM size for systems <8GB RAM + ''; + example = "32G"; + }; }; - }; }; }; + }; + }; config = lib.mkMerge [ { diff --git a/secrets.nix b/secrets.nix index 2fd6786..a7f5a00 100644 --- a/secrets.nix +++ b/secrets.nix @@ -54,27 +54,10 @@ let in lenStr >= lenSuffix && lib.substring (lenStr - lenSuffix) lenSuffix str == suffix; - hasPrefix = - prefix: str: - let - lenPrefix = lib.stringLength prefix; - in - lib.stringLength str >= lenPrefix && lib.substring 0 lenPrefix str == prefix; - nameValuePair = name: value: { inherit name value; }; secretsPath = ./secrets; - # Helper to convert SSH public key content to age public key - sshToAge = - sshPubKey: - let - # This is a simple check - in practice, use ssh-to-age tool - # For now, we'll just use the keys as-is if they look like age keys - trimmed = lib.replaceStrings [ "\n" ] [ "" ] sshPubKey; - in - if lib.substring 0 4 trimmed == "age1" then trimmed else null; # Will need manual conversion with ssh-to-age - # Read all directories in secrets/ secretDirs = if lib.pathExists secretsPath then lib.readDir secretsPath else { }; @@ -181,22 +164,23 @@ let # Generate wildcard rules for each directory to allow creating new secrets wildcardRules = lib.listToAttrs ( - lib.concatMap ( - dir: - [ - # Match with and without .age extension for ragenix compatibility - (nameValuePair "secrets/${dir}/*" { - publicKeys = let + lib.concatMap (dir: [ + # Match with and without .age extension for ragenix compatibility + (nameValuePair "secrets/${dir}/*" { + publicKeys = + let recipients = getRecipients "secrets/${dir}/dummy.age"; - in unique (lib.filter (k: k != null && k != "") recipients); - }) - (nameValuePair "secrets/${dir}/*.age" { - publicKeys = let + in + unique (lib.filter (k: k != null && k != "") recipients); + }) + (nameValuePair "secrets/${dir}/*.age" { + publicKeys = + let recipients = getRecipients "secrets/${dir}/dummy.age"; - in unique (lib.filter (k: k != null && k != "") recipients); - }) - ] - ) (lib.filter (d: d != "admins") directories) + in + unique (lib.filter (k: k != null && k != "") recipients); + }) + ]) (lib.filter (d: d != "admins") directories) ); in diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 880aa47..b2633c6 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -54,27 +54,10 @@ let in lenStr >= lenSuffix && lib.substring (lenStr - lenSuffix) lenSuffix str == suffix; - hasPrefix = - prefix: str: - let - lenPrefix = lib.stringLength prefix; - in - lib.stringLength str >= lenPrefix && lib.substring 0 lenPrefix str == prefix; - nameValuePair = name: value: { inherit name value; }; secretsPath = ./secrets; - # Helper to convert SSH public key content to age public key - sshToAge = - sshPubKey: - let - # This is a simple check - in practice, use ssh-to-age tool - # For now, we'll just use the keys as-is if they look like age keys - trimmed = lib.replaceStrings [ "\n" ] [ "" ] sshPubKey; - in - if lib.substring 0 4 trimmed == "age1" then trimmed else null; # Will need manual conversion with ssh-to-age - # Read all directories in secrets/ secretDirs = if lib.pathExists secretsPath then lib.readDir secretsPath else { }; diff --git a/sw/secrets.nix b/sw/secrets.nix index 95862ff..9090a66 100644 --- a/sw/secrets.nix +++ b/sw/secrets.nix @@ -195,7 +195,10 @@ in # This is needed because age can't reliably use OpenSSH private keys directly # Must run before agenix tries to decrypt secrets system.activationScripts.convertSshToAge = { - deps = [ "users" "groups" ]; + deps = [ + "users" + "groups" + ]; text = '' mkdir -p /etc/age if [ -f /etc/ssh/ssh_host_ed25519_key ]; then