Include agenix module and package directly
Avoids adding an extra flake input only to fetch a single module and package.
This commit is contained in:
		
							parent
							
								
									1fba0a14a8
								
							
						
					
					
						commit
						9a7e600e7b
					
				
							
								
								
									
										82
									
								
								flake.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										82
									
								
								flake.lock
									
									
									
										generated
									
									
									
								
							| @ -1,71 +1,5 @@ | |||||||
| { | { | ||||||
|   "nodes": { |   "nodes": { | ||||||
|     "agenix": { |  | ||||||
|       "inputs": { |  | ||||||
|         "darwin": "darwin", |  | ||||||
|         "home-manager": "home-manager", |  | ||||||
|         "nixpkgs": [ |  | ||||||
|           "nixpkgs" |  | ||||||
|         ], |  | ||||||
|         "systems": "systems" |  | ||||||
|       }, |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1750173260, |  | ||||||
|         "narHash": "sha256-9P1FziAwl5+3edkfFcr5HeGtQUtrSdk/MksX39GieoA=", |  | ||||||
|         "owner": "ryantm", |  | ||||||
|         "repo": "agenix", |  | ||||||
|         "rev": "531beac616433bac6f9e2a19feb8e99a22a66baf", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "ryantm", |  | ||||||
|         "repo": "agenix", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "darwin": { |  | ||||||
|       "inputs": { |  | ||||||
|         "nixpkgs": [ |  | ||||||
|           "agenix", |  | ||||||
|           "nixpkgs" |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1744478979, |  | ||||||
|         "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", |  | ||||||
|         "owner": "lnl7", |  | ||||||
|         "repo": "nix-darwin", |  | ||||||
|         "rev": "43975d782b418ebf4969e9ccba82466728c2851b", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "lnl7", |  | ||||||
|         "ref": "master", |  | ||||||
|         "repo": "nix-darwin", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "home-manager": { |  | ||||||
|       "inputs": { |  | ||||||
|         "nixpkgs": [ |  | ||||||
|           "agenix", |  | ||||||
|           "nixpkgs" |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1745494811, |  | ||||||
|         "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", |  | ||||||
|         "owner": "nix-community", |  | ||||||
|         "repo": "home-manager", |  | ||||||
|         "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "nix-community", |  | ||||||
|         "repo": "home-manager", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "nixpkgs": { |     "nixpkgs": { | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1752436162, |         "lastModified": 1752436162, | ||||||
| @ -84,24 +18,8 @@ | |||||||
|     }, |     }, | ||||||
|     "root": { |     "root": { | ||||||
|       "inputs": { |       "inputs": { | ||||||
|         "agenix": "agenix", |  | ||||||
|         "nixpkgs": "nixpkgs" |         "nixpkgs": "nixpkgs" | ||||||
|       } |       } | ||||||
|     }, |  | ||||||
|     "systems": { |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1681028828, |  | ||||||
|         "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", |  | ||||||
|         "owner": "nix-systems", |  | ||||||
|         "repo": "default", |  | ||||||
|         "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "nix-systems", |  | ||||||
|         "repo": "default", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "root": "root", |   "root": "root", | ||||||
|  | |||||||
| @ -1,15 +1,13 @@ | |||||||
| { | { | ||||||
|   inputs = { |   inputs = { | ||||||
|     nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; |     nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; | ||||||
|     agenix.url = "github:ryantm/agenix"; |  | ||||||
|     agenix.inputs.nixpkgs.follows = "nixpkgs"; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   outputs = { self, nixpkgs, agenix, ... }: |   outputs = { self, nixpkgs, ... }: | ||||||
| let | let | ||||||
|   mkConf = name: nixpkgs.lib.nixosSystem { |   mkConf = name: nixpkgs.lib.nixosSystem { | ||||||
|     system = "x86_64-linux"; |     system = "x86_64-linux"; | ||||||
|     specialArgs = { inherit nixpkgs agenix; theFlake = self; }; |     specialArgs = { inherit nixpkgs; theFlake = self; }; | ||||||
|     modules = [ "${self.outPath}/m/${name}/configuration.nix" ]; |     modules = [ "${self.outPath}/m/${name}/configuration.nix" ]; | ||||||
|   }; |   }; | ||||||
|   # For now we only support x86 |   # For now we only support x86 | ||||||
|  | |||||||
| @ -1,9 +1,8 @@ | |||||||
| { agenix, ... }: | { pkgs, ... }: | ||||||
| 
 | 
 | ||||||
| { | { | ||||||
|   imports = [ agenix.nixosModules.default ]; |   imports = [ ../../module/agenix.nix ]; | ||||||
| 
 | 
 | ||||||
|   environment.systemPackages = [ |   # Add agenix to system packages | ||||||
|     agenix.packages.x86_64-linux.default |   environment.systemPackages = [ pkgs.agenix ]; | ||||||
|   ]; |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										357
									
								
								m/module/agenix.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										357
									
								
								m/module/agenix.nix
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,357 @@ | |||||||
|  | { | ||||||
|  |   config, | ||||||
|  |   options, | ||||||
|  |   lib, | ||||||
|  |   pkgs, | ||||||
|  |   ... | ||||||
|  | }: | ||||||
|  | with lib; | ||||||
|  | let | ||||||
|  |   cfg = config.age; | ||||||
|  | 
 | ||||||
|  |   isDarwin = lib.attrsets.hasAttrByPath [ "environment" "darwinConfig" ] options; | ||||||
|  | 
 | ||||||
|  |   ageBin = config.age.ageBin; | ||||||
|  | 
 | ||||||
|  |   users = config.users.users; | ||||||
|  | 
 | ||||||
|  |   sysusersEnabled = | ||||||
|  |     if isDarwin then | ||||||
|  |       false | ||||||
|  |     else | ||||||
|  |       options.systemd ? sysusers && (config.systemd.sysusers.enable || config.services.userborn.enable); | ||||||
|  | 
 | ||||||
|  |   mountCommand = | ||||||
|  |     if isDarwin then | ||||||
|  |       '' | ||||||
|  |         if ! diskutil info "${cfg.secretsMountPoint}" &> /dev/null; then | ||||||
|  |             num_sectors=1048576 | ||||||
|  |             dev=$(hdiutil attach -nomount ram://"$num_sectors" | sed 's/[[:space:]]*$//') | ||||||
|  |             newfs_hfs -v agenix "$dev" | ||||||
|  |             mount -t hfs -o nobrowse,nodev,nosuid,-m=0751 "$dev" "${cfg.secretsMountPoint}" | ||||||
|  |         fi | ||||||
|  |       '' | ||||||
|  |     else | ||||||
|  |       '' | ||||||
|  |         grep -q "${cfg.secretsMountPoint} ramfs" /proc/mounts || | ||||||
|  |           mount -t ramfs none "${cfg.secretsMountPoint}" -o nodev,nosuid,mode=0751 | ||||||
|  |       ''; | ||||||
|  |   newGeneration = '' | ||||||
|  |     _agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)" | ||||||
|  |     (( ++_agenix_generation )) | ||||||
|  |     echo "[agenix] creating new generation in ${cfg.secretsMountPoint}/$_agenix_generation" | ||||||
|  |     mkdir -p "${cfg.secretsMountPoint}" | ||||||
|  |     chmod 0751 "${cfg.secretsMountPoint}" | ||||||
|  |     ${mountCommand} | ||||||
|  |     mkdir -p "${cfg.secretsMountPoint}/$_agenix_generation" | ||||||
|  |     chmod 0751 "${cfg.secretsMountPoint}/$_agenix_generation" | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   chownGroup = if isDarwin then "admin" else "keys"; | ||||||
|  |   # chown the secrets mountpoint and the current generation to the keys group | ||||||
|  |   # instead of leaving it root:root. | ||||||
|  |   chownMountPoint = '' | ||||||
|  |     chown :${chownGroup} "${cfg.secretsMountPoint}" "${cfg.secretsMountPoint}/$_agenix_generation" | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   setTruePath = secretType: '' | ||||||
|  |     ${ | ||||||
|  |       if secretType.symlink then | ||||||
|  |         '' | ||||||
|  |           _truePath="${cfg.secretsMountPoint}/$_agenix_generation/${secretType.name}" | ||||||
|  |         '' | ||||||
|  |       else | ||||||
|  |         '' | ||||||
|  |           _truePath="${secretType.path}" | ||||||
|  |         '' | ||||||
|  |     } | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   installSecret = secretType: '' | ||||||
|  |     ${setTruePath secretType} | ||||||
|  |     echo "decrypting '${secretType.file}' to '$_truePath'..." | ||||||
|  |     TMP_FILE="$_truePath.tmp" | ||||||
|  | 
 | ||||||
|  |     IDENTITIES=() | ||||||
|  |     for identity in ${toString cfg.identityPaths}; do | ||||||
|  |       test -r "$identity" || continue | ||||||
|  |       test -s "$identity" || continue | ||||||
|  |       IDENTITIES+=(-i) | ||||||
|  |       IDENTITIES+=("$identity") | ||||||
|  |     done | ||||||
|  | 
 | ||||||
|  |     test "''${#IDENTITIES[@]}" -eq 0 && echo "[agenix] WARNING: no readable identities found!" | ||||||
|  | 
 | ||||||
|  |     mkdir -p "$(dirname "$_truePath")" | ||||||
|  |     [ "${secretType.path}" != "${cfg.secretsDir}/${secretType.name}" ] && mkdir -p "$(dirname "${secretType.path}")" | ||||||
|  |     ( | ||||||
|  |       umask u=r,g=,o= | ||||||
|  |       test -f "${secretType.file}" || echo '[agenix] WARNING: encrypted file ${secretType.file} does not exist!' | ||||||
|  |       test -d "$(dirname "$TMP_FILE")" || echo "[agenix] WARNING: $(dirname "$TMP_FILE") does not exist!" | ||||||
|  |       LANG=${ | ||||||
|  |         config.i18n.defaultLocale or "C" | ||||||
|  |       } ${ageBin} --decrypt "''${IDENTITIES[@]}" -o "$TMP_FILE" "${secretType.file}" | ||||||
|  |     ) | ||||||
|  |     chmod ${secretType.mode} "$TMP_FILE" | ||||||
|  |     mv -f "$TMP_FILE" "$_truePath" | ||||||
|  | 
 | ||||||
|  |     ${optionalString secretType.symlink '' | ||||||
|  |       [ "${secretType.path}" != "${cfg.secretsDir}/${secretType.name}" ] && ln -sfT "${cfg.secretsDir}/${secretType.name}" "${secretType.path}" | ||||||
|  |     ''} | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   testIdentities = map (path: '' | ||||||
|  |     test -f ${path} || echo '[agenix] WARNING: config.age.identityPaths entry ${path} not present!' | ||||||
|  |   '') cfg.identityPaths; | ||||||
|  | 
 | ||||||
|  |   cleanupAndLink = '' | ||||||
|  |     _agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)" | ||||||
|  |     (( ++_agenix_generation )) | ||||||
|  |     echo "[agenix] symlinking new secrets to ${cfg.secretsDir} (generation $_agenix_generation)..." | ||||||
|  |     ln -sfT "${cfg.secretsMountPoint}/$_agenix_generation" ${cfg.secretsDir} | ||||||
|  | 
 | ||||||
|  |     (( _agenix_generation > 1 )) && { | ||||||
|  |     echo "[agenix] removing old secrets (generation $(( _agenix_generation - 1 )))..." | ||||||
|  |     rm -rf "${cfg.secretsMountPoint}/$(( _agenix_generation - 1 ))" | ||||||
|  |     } | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   installSecrets = builtins.concatStringsSep "\n" ( | ||||||
|  |     [ "echo '[agenix] decrypting secrets...'" ] | ||||||
|  |     ++ testIdentities | ||||||
|  |     ++ (map installSecret (builtins.attrValues cfg.secrets)) | ||||||
|  |     ++ [ cleanupAndLink ] | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   chownSecret = secretType: '' | ||||||
|  |     ${setTruePath secretType} | ||||||
|  |     chown ${secretType.owner}:${secretType.group} "$_truePath" | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   chownSecrets = builtins.concatStringsSep "\n" ( | ||||||
|  |     [ "echo '[agenix] chowning...'" ] | ||||||
|  |     ++ [ chownMountPoint ] | ||||||
|  |     ++ (map chownSecret (builtins.attrValues cfg.secrets)) | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   secretType = types.submodule ( | ||||||
|  |     { config, ... }: | ||||||
|  |     { | ||||||
|  |       options = { | ||||||
|  |         name = mkOption { | ||||||
|  |           type = types.str; | ||||||
|  |           default = config._module.args.name; | ||||||
|  |           defaultText = literalExpression "config._module.args.name"; | ||||||
|  |           description = '' | ||||||
|  |             Name of the file used in {option}`age.secretsDir` | ||||||
|  |           ''; | ||||||
|  |         }; | ||||||
|  |         file = mkOption { | ||||||
|  |           type = types.path; | ||||||
|  |           description = '' | ||||||
|  |             Age file the secret is loaded from. | ||||||
|  |           ''; | ||||||
|  |         }; | ||||||
|  |         path = mkOption { | ||||||
|  |           type = types.str; | ||||||
|  |           default = "${cfg.secretsDir}/${config.name}"; | ||||||
|  |           defaultText = literalExpression '' | ||||||
|  |             "''${cfg.secretsDir}/''${config.name}" | ||||||
|  |           ''; | ||||||
|  |           description = '' | ||||||
|  |             Path where the decrypted secret is installed. | ||||||
|  |           ''; | ||||||
|  |         }; | ||||||
|  |         mode = mkOption { | ||||||
|  |           type = types.str; | ||||||
|  |           default = "0400"; | ||||||
|  |           description = '' | ||||||
|  |             Permissions mode of the decrypted secret in a format understood by chmod. | ||||||
|  |           ''; | ||||||
|  |         }; | ||||||
|  |         owner = mkOption { | ||||||
|  |           type = types.str; | ||||||
|  |           default = "0"; | ||||||
|  |           description = '' | ||||||
|  |             User of the decrypted secret. | ||||||
|  |           ''; | ||||||
|  |         }; | ||||||
|  |         group = mkOption { | ||||||
|  |           type = types.str; | ||||||
|  |           default = users.${config.owner}.group or "0"; | ||||||
|  |           defaultText = literalExpression '' | ||||||
|  |             users.''${config.owner}.group or "0" | ||||||
|  |           ''; | ||||||
|  |           description = '' | ||||||
|  |             Group of the decrypted secret. | ||||||
|  |           ''; | ||||||
|  |         }; | ||||||
|  |         symlink = mkEnableOption "symlinking secrets to their destination" // { | ||||||
|  |           default = true; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     } | ||||||
|  |   ); | ||||||
|  | in | ||||||
|  | { | ||||||
|  |   imports = [ | ||||||
|  |     (mkRenamedOptionModule [ "age" "sshKeyPaths" ] [ "age" "identityPaths" ]) | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   options.age = { | ||||||
|  |     ageBin = mkOption { | ||||||
|  |       type = types.str; | ||||||
|  |       default = "${pkgs.age}/bin/age"; | ||||||
|  |       defaultText = literalExpression '' | ||||||
|  |         "''${pkgs.age}/bin/age" | ||||||
|  |       ''; | ||||||
|  |       description = '' | ||||||
|  |         The age executable to use. | ||||||
|  |       ''; | ||||||
|  |     }; | ||||||
|  |     secrets = mkOption { | ||||||
|  |       type = types.attrsOf secretType; | ||||||
|  |       default = { }; | ||||||
|  |       description = '' | ||||||
|  |         Attrset of secrets. | ||||||
|  |       ''; | ||||||
|  |     }; | ||||||
|  |     secretsDir = mkOption { | ||||||
|  |       type = types.path; | ||||||
|  |       default = "/run/agenix"; | ||||||
|  |       description = '' | ||||||
|  |         Folder where secrets are symlinked to | ||||||
|  |       ''; | ||||||
|  |     }; | ||||||
|  |     secretsMountPoint = mkOption { | ||||||
|  |       type = | ||||||
|  |         types.addCheck types.str ( | ||||||
|  |           s: | ||||||
|  |           (builtins.match "[ \t\n]*" s) == null # non-empty | ||||||
|  |           && (builtins.match ".+/" s) == null | ||||||
|  |         ) # without trailing slash | ||||||
|  |         // { | ||||||
|  |           description = "${types.str.description} (with check: non-empty without trailing slash)"; | ||||||
|  |         }; | ||||||
|  |       default = "/run/agenix.d"; | ||||||
|  |       description = '' | ||||||
|  |         Where secrets are created before they are symlinked to {option}`age.secretsDir` | ||||||
|  |       ''; | ||||||
|  |     }; | ||||||
|  |     identityPaths = mkOption { | ||||||
|  |       type = types.listOf types.path; | ||||||
|  |       default = | ||||||
|  |         if isDarwin then | ||||||
|  |           [ | ||||||
|  |             "/etc/ssh/ssh_host_ed25519_key" | ||||||
|  |             "/etc/ssh/ssh_host_rsa_key" | ||||||
|  |           ] | ||||||
|  |         else if (config.services.openssh.enable or false) then | ||||||
|  |           map (e: e.path) ( | ||||||
|  |             lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys | ||||||
|  |           ) | ||||||
|  |         else | ||||||
|  |           [ ]; | ||||||
|  |       defaultText = literalExpression '' | ||||||
|  |         if isDarwin | ||||||
|  |         then [ | ||||||
|  |           "/etc/ssh/ssh_host_ed25519_key" | ||||||
|  |           "/etc/ssh/ssh_host_rsa_key" | ||||||
|  |         ] | ||||||
|  |         else if (config.services.openssh.enable or false) | ||||||
|  |         then map (e: e.path) (lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys) | ||||||
|  |         else []; | ||||||
|  |       ''; | ||||||
|  |       description = '' | ||||||
|  |         Path to SSH keys to be used as identities in age decryption. | ||||||
|  |       ''; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   config = mkIf (cfg.secrets != { }) (mkMerge [ | ||||||
|  |     { | ||||||
|  |       assertions = [ | ||||||
|  |         { | ||||||
|  |           assertion = cfg.identityPaths != [ ]; | ||||||
|  |           message = "age.identityPaths must be set, for example by enabling openssh."; | ||||||
|  |         } | ||||||
|  |       ]; | ||||||
|  |     } | ||||||
|  |     (optionalAttrs (!isDarwin) { | ||||||
|  |       # When using sysusers we no longer be started as an activation script | ||||||
|  |       # because those are started in initrd while sysusers is started later. | ||||||
|  |       systemd.services.agenix-install-secrets = mkIf sysusersEnabled { | ||||||
|  |         wantedBy = [ "sysinit.target" ]; | ||||||
|  |         after = [ "systemd-sysusers.service" ]; | ||||||
|  |         unitConfig.DefaultDependencies = "no"; | ||||||
|  | 
 | ||||||
|  |         path = [ pkgs.mount ]; | ||||||
|  |         serviceConfig = { | ||||||
|  |           Type = "oneshot"; | ||||||
|  |           ExecStart = pkgs.writeShellScript "agenix-install" (concatLines [ | ||||||
|  |             newGeneration | ||||||
|  |             installSecrets | ||||||
|  |             chownSecrets | ||||||
|  |           ]); | ||||||
|  |           RemainAfterExit = true; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       # Create a new directory full of secrets for symlinking (this helps | ||||||
|  |       # ensure removed secrets are actually removed, or at least become | ||||||
|  |       # invalid symlinks). | ||||||
|  |       system.activationScripts = mkIf (!sysusersEnabled) { | ||||||
|  |         agenixNewGeneration = { | ||||||
|  |           text = newGeneration; | ||||||
|  |           deps = [ | ||||||
|  |             "specialfs" | ||||||
|  |           ]; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         agenixInstall = { | ||||||
|  |           text = installSecrets; | ||||||
|  |           deps = [ | ||||||
|  |             "agenixNewGeneration" | ||||||
|  |             "specialfs" | ||||||
|  |           ]; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         # So user passwords can be encrypted. | ||||||
|  |         users.deps = [ "agenixInstall" ]; | ||||||
|  | 
 | ||||||
|  |         # Change ownership and group after users and groups are made. | ||||||
|  |         agenixChown = { | ||||||
|  |           text = chownSecrets; | ||||||
|  |           deps = [ | ||||||
|  |             "users" | ||||||
|  |             "groups" | ||||||
|  |           ]; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         # So other activation scripts can depend on agenix being done. | ||||||
|  |         agenix = { | ||||||
|  |           text = ""; | ||||||
|  |           deps = [ "agenixChown" ]; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     (optionalAttrs isDarwin { | ||||||
|  |       launchd.daemons.activate-agenix = { | ||||||
|  |         script = '' | ||||||
|  |           set -e | ||||||
|  |           set -o pipefail | ||||||
|  |           export PATH="${pkgs.gnugrep}/bin:${pkgs.coreutils}/bin:@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin" | ||||||
|  |           ${newGeneration} | ||||||
|  |           ${installSecrets} | ||||||
|  |           ${chownSecrets} | ||||||
|  |           exit 0 | ||||||
|  |         ''; | ||||||
|  |         serviceConfig = { | ||||||
|  |           RunAtLoad = true; | ||||||
|  |           KeepAlive.SuccessfulExit = false; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     }) | ||||||
|  |   ]); | ||||||
|  | } | ||||||
| @ -7,6 +7,7 @@ let | |||||||
|   callPackage = final.callPackage; |   callPackage = final.callPackage; | ||||||
| 
 | 
 | ||||||
|   bscPkgs = { |   bscPkgs = { | ||||||
|  |     agenix = prev.callPackage ./pkgs/agenix/default.nix { }; | ||||||
|     amd-uprof = prev.callPackage ./pkgs/amd-uprof/default.nix { }; |     amd-uprof = prev.callPackage ./pkgs/amd-uprof/default.nix { }; | ||||||
|     bench6 = callPackage ./pkgs/bench6/default.nix { }; |     bench6 = callPackage ./pkgs/bench6/default.nix { }; | ||||||
|     bigotes = callPackage ./pkgs/bigotes/default.nix { }; |     bigotes = callPackage ./pkgs/bigotes/default.nix { }; | ||||||
|  | |||||||
							
								
								
									
										212
									
								
								pkgs/agenix/agenix.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								pkgs/agenix/agenix.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,212 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | set -Eeuo pipefail | ||||||
|  | 
 | ||||||
|  | PACKAGE="agenix" | ||||||
|  | 
 | ||||||
|  | function show_help () { | ||||||
|  |   echo "$PACKAGE - edit and rekey age secret files" | ||||||
|  |   echo " " | ||||||
|  |   echo "$PACKAGE -e FILE [-i PRIVATE_KEY]" | ||||||
|  |   echo "$PACKAGE -r [-i PRIVATE_KEY]" | ||||||
|  |   echo ' ' | ||||||
|  |   echo 'options:' | ||||||
|  |   echo '-h, --help                show help' | ||||||
|  |   # shellcheck disable=SC2016 | ||||||
|  |   echo '-e, --edit FILE           edits FILE using $EDITOR' | ||||||
|  |   echo '-r, --rekey               re-encrypts all secrets with specified recipients' | ||||||
|  |   echo '-d, --decrypt FILE        decrypts FILE to STDOUT' | ||||||
|  |   echo '-i, --identity            identity to use when decrypting' | ||||||
|  |   echo '-v, --verbose             verbose output' | ||||||
|  |   echo ' ' | ||||||
|  |   echo 'FILE an age-encrypted file' | ||||||
|  |   echo ' ' | ||||||
|  |   echo 'PRIVATE_KEY a path to a private SSH key used to decrypt file' | ||||||
|  |   echo ' ' | ||||||
|  |   echo 'EDITOR environment variable of editor to use when editing FILE' | ||||||
|  |   echo ' ' | ||||||
|  |   echo 'If STDIN is not interactive, EDITOR will be set to "cp /dev/stdin"' | ||||||
|  |   echo ' ' | ||||||
|  |   echo 'RULES environment variable with path to Nix file specifying recipient public keys.' | ||||||
|  |   echo "Defaults to './secrets.nix'" | ||||||
|  |   echo ' ' | ||||||
|  |   echo "agenix version: @version@" | ||||||
|  |   echo "age binary path: @ageBin@" | ||||||
|  |   echo "age version: $(@ageBin@ --version)" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function warn() { | ||||||
|  |   printf '%s\n' "$*" >&2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function err() { | ||||||
|  |   warn "$*" | ||||||
|  |   exit 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | test $# -eq 0 && (show_help && exit 1) | ||||||
|  | 
 | ||||||
|  | REKEY=0 | ||||||
|  | DECRYPT_ONLY=0 | ||||||
|  | DEFAULT_DECRYPT=(--decrypt) | ||||||
|  | 
 | ||||||
|  | while test $# -gt 0; do | ||||||
|  |   case "$1" in | ||||||
|  |     -h|--help) | ||||||
|  |       show_help | ||||||
|  |       exit 0 | ||||||
|  |       ;; | ||||||
|  |     -e|--edit) | ||||||
|  |       shift | ||||||
|  |       if test $# -gt 0; then | ||||||
|  |         export FILE=$1 | ||||||
|  |       else | ||||||
|  |         echo "no FILE specified" | ||||||
|  |         exit 1 | ||||||
|  |       fi | ||||||
|  |       shift | ||||||
|  |       ;; | ||||||
|  |     -i|--identity) | ||||||
|  |       shift | ||||||
|  |       if test $# -gt 0; then | ||||||
|  |         DEFAULT_DECRYPT+=(--identity "$1") | ||||||
|  |       else | ||||||
|  |         echo "no PRIVATE_KEY specified" | ||||||
|  |         exit 1 | ||||||
|  |       fi | ||||||
|  |       shift | ||||||
|  |       ;; | ||||||
|  |     -r|--rekey) | ||||||
|  |       shift | ||||||
|  |       REKEY=1 | ||||||
|  |       ;; | ||||||
|  |     -d|--decrypt) | ||||||
|  |       shift | ||||||
|  |       DECRYPT_ONLY=1 | ||||||
|  |       if test $# -gt 0; then | ||||||
|  |         export FILE=$1 | ||||||
|  |       else | ||||||
|  |         echo "no FILE specified" | ||||||
|  |         exit 1 | ||||||
|  |       fi | ||||||
|  |       shift | ||||||
|  |       ;; | ||||||
|  |     -v|--verbose) | ||||||
|  |       shift | ||||||
|  |       set -x | ||||||
|  |       ;; | ||||||
|  |     *) | ||||||
|  |       show_help | ||||||
|  |       exit 1 | ||||||
|  |       ;; | ||||||
|  |   esac | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | RULES=${RULES:-./secrets.nix} | ||||||
|  | function cleanup { | ||||||
|  |     if [ -n "${CLEARTEXT_DIR+x}" ] | ||||||
|  |     then | ||||||
|  |         rm -rf -- "$CLEARTEXT_DIR" | ||||||
|  |     fi | ||||||
|  |     if [ -n "${REENCRYPTED_DIR+x}" ] | ||||||
|  |     then | ||||||
|  |         rm -rf -- "$REENCRYPTED_DIR" | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  | trap "cleanup" 0 2 3 15 | ||||||
|  | 
 | ||||||
|  | function keys { | ||||||
|  |     (@nixInstantiate@ --json --eval --strict -E "(let rules = import $RULES; in rules.\"$1\".publicKeys)" | @jqBin@ -r .[]) || exit 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function armor { | ||||||
|  |     (@nixInstantiate@ --json --eval --strict -E "(let rules = import $RULES; in (builtins.hasAttr \"armor\" rules.\"$1\" && rules.\"$1\".armor))") || exit 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function decrypt { | ||||||
|  |     FILE=$1 | ||||||
|  |     KEYS=$2 | ||||||
|  |     if [ -z "$KEYS" ] | ||||||
|  |     then | ||||||
|  |         err "There is no rule for $FILE in $RULES." | ||||||
|  |     fi | ||||||
|  | 
 | ||||||
|  |     if [ -f "$FILE" ] | ||||||
|  |     then | ||||||
|  |         DECRYPT=("${DEFAULT_DECRYPT[@]}") | ||||||
|  |         if [[ "${DECRYPT[*]}" != *"--identity"* ]]; then | ||||||
|  |             if [ -f "$HOME/.ssh/id_rsa" ]; then | ||||||
|  |                 DECRYPT+=(--identity "$HOME/.ssh/id_rsa") | ||||||
|  |             fi | ||||||
|  |             if [ -f "$HOME/.ssh/id_ed25519" ]; then | ||||||
|  |                 DECRYPT+=(--identity "$HOME/.ssh/id_ed25519") | ||||||
|  |             fi | ||||||
|  |         fi | ||||||
|  |         if [[ "${DECRYPT[*]}" != *"--identity"* ]]; then | ||||||
|  |           err "No identity found to decrypt $FILE. Try adding an SSH key at $HOME/.ssh/id_rsa or $HOME/.ssh/id_ed25519 or using the --identity flag to specify a file." | ||||||
|  |         fi | ||||||
|  | 
 | ||||||
|  |         @ageBin@ "${DECRYPT[@]}" -- "$FILE" || exit 1 | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function edit { | ||||||
|  |     FILE=$1 | ||||||
|  |     KEYS=$(keys "$FILE") || exit 1 | ||||||
|  |     ARMOR=$(armor "$FILE") || exit 1 | ||||||
|  | 
 | ||||||
|  |     CLEARTEXT_DIR=$(@mktempBin@ -d) | ||||||
|  |     CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename -- "$FILE")" | ||||||
|  |     DEFAULT_DECRYPT+=(-o "$CLEARTEXT_FILE") | ||||||
|  | 
 | ||||||
|  |     decrypt "$FILE" "$KEYS" || exit 1 | ||||||
|  | 
 | ||||||
|  |     [ ! -f "$CLEARTEXT_FILE" ] || cp -- "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before" | ||||||
|  | 
 | ||||||
|  |     [ -t 0 ] || EDITOR='cp -- /dev/stdin' | ||||||
|  | 
 | ||||||
|  |     $EDITOR "$CLEARTEXT_FILE" | ||||||
|  | 
 | ||||||
|  |     if [ ! -f "$CLEARTEXT_FILE" ] | ||||||
|  |     then | ||||||
|  |       warn "$FILE wasn't created." | ||||||
|  |       return | ||||||
|  |     fi | ||||||
|  |     [ -f "$FILE" ] && [ "$EDITOR" != ":" ] && @diffBin@ -q -- "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return | ||||||
|  | 
 | ||||||
|  |     ENCRYPT=() | ||||||
|  |     if [[ "$ARMOR" == "true" ]]; then | ||||||
|  |         ENCRYPT+=(--armor) | ||||||
|  |     fi | ||||||
|  |     while IFS= read -r key | ||||||
|  |     do | ||||||
|  |         if [ -n "$key" ]; then | ||||||
|  |             ENCRYPT+=(--recipient "$key") | ||||||
|  |         fi | ||||||
|  |     done <<< "$KEYS" | ||||||
|  | 
 | ||||||
|  |     REENCRYPTED_DIR=$(@mktempBin@ -d) | ||||||
|  |     REENCRYPTED_FILE="$REENCRYPTED_DIR/$(basename -- "$FILE")" | ||||||
|  | 
 | ||||||
|  |     ENCRYPT+=(-o "$REENCRYPTED_FILE") | ||||||
|  | 
 | ||||||
|  |     @ageBin@ "${ENCRYPT[@]}" <"$CLEARTEXT_FILE" || exit 1 | ||||||
|  | 
 | ||||||
|  |     mkdir -p -- "$(dirname -- "$FILE")" | ||||||
|  | 
 | ||||||
|  |     mv -f -- "$REENCRYPTED_FILE" "$FILE" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function rekey { | ||||||
|  |     FILES=$( (@nixInstantiate@ --json --eval -E "(let rules = import $RULES; in builtins.attrNames rules)"  | @jqBin@ -r .[]) || exit 1) | ||||||
|  | 
 | ||||||
|  |     for FILE in $FILES | ||||||
|  |     do | ||||||
|  |         warn "rekeying $FILE..." | ||||||
|  |         EDITOR=: edit "$FILE" | ||||||
|  |         cleanup | ||||||
|  |     done | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [ $REKEY -eq 1 ] && rekey && exit 0 | ||||||
|  | [ $DECRYPT_ONLY -eq 1 ] && DEFAULT_DECRYPT+=("-o" "-") && decrypt "${FILE}" "$(keys "$FILE")" && exit 0 | ||||||
|  | edit "$FILE" && cleanup && exit 0 | ||||||
							
								
								
									
										66
									
								
								pkgs/agenix/default.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								pkgs/agenix/default.nix
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | { | ||||||
|  |   lib, | ||||||
|  |   stdenv, | ||||||
|  |   age, | ||||||
|  |   jq, | ||||||
|  |   nix, | ||||||
|  |   mktemp, | ||||||
|  |   diffutils, | ||||||
|  |   replaceVars, | ||||||
|  |   ageBin ? "${age}/bin/age", | ||||||
|  |   shellcheck, | ||||||
|  | }: | ||||||
|  | let | ||||||
|  |   bin = "${placeholder "out"}/bin/agenix"; | ||||||
|  | in | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   pname = "agenix"; | ||||||
|  |   version = "0.15.0"; | ||||||
|  |   src = replaceVars ./agenix.sh { | ||||||
|  |     inherit ageBin version; | ||||||
|  |     jqBin = "${jq}/bin/jq"; | ||||||
|  |     nixInstantiate = "${nix}/bin/nix-instantiate"; | ||||||
|  |     mktempBin = "${mktemp}/bin/mktemp"; | ||||||
|  |     diffBin = "${diffutils}/bin/diff"; | ||||||
|  |   }; | ||||||
|  |   dontUnpack = true; | ||||||
|  |   doInstallCheck = true; | ||||||
|  |   installCheckInputs = [ shellcheck ]; | ||||||
|  |   postInstallCheck = '' | ||||||
|  |     shellcheck ${bin} | ||||||
|  |     ${bin} -h | grep ${version} | ||||||
|  | 
 | ||||||
|  |     test_tmp=$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir') | ||||||
|  |     export HOME="$test_tmp/home" | ||||||
|  |     export NIX_STORE_DIR="$test_tmp/nix/store" | ||||||
|  |     export NIX_STATE_DIR="$test_tmp/nix/var" | ||||||
|  |     mkdir -p "$HOME" "$NIX_STORE_DIR" "$NIX_STATE_DIR" | ||||||
|  |     function cleanup { | ||||||
|  |       rm -rf "$test_tmp" | ||||||
|  |     } | ||||||
|  |     trap "cleanup" 0 2 3 15 | ||||||
|  | 
 | ||||||
|  |     mkdir -p $HOME/.ssh | ||||||
|  |     cp -r "${./example}" $HOME/secrets | ||||||
|  |     chmod -R u+rw $HOME/secrets | ||||||
|  |     ( | ||||||
|  |     umask u=rw,g=r,o=r | ||||||
|  |     cp ${./example_keys/user1.pub} $HOME/.ssh/id_ed25519.pub | ||||||
|  |     chown $UID $HOME/.ssh/id_ed25519.pub | ||||||
|  |     ) | ||||||
|  |     ( | ||||||
|  |     umask u=rw,g=,o= | ||||||
|  |     cp ${./example_keys/user1} $HOME/.ssh/id_ed25519 | ||||||
|  |     chown $UID $HOME/.ssh/id_ed25519 | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     cd $HOME/secrets | ||||||
|  |     test $(${bin} -d secret1.age) = "hello" | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   installPhase = '' | ||||||
|  |     install -D $src ${bin} | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   meta.description = "age-encrypted secrets for NixOS"; | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								pkgs/agenix/example/-leading-hyphen-filename.age
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkgs/agenix/example/-leading-hyphen-filename.age
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | age-encryption.org/v1 | ||||||
|  | -> ssh-ed25519 V3XmEA zirqdzZZ1E+sedBn7fbEHq4ntLEkokZ4GctarBBOHXY | ||||||
|  | Rvs5YHaAUeCZyNwPedubPcHClWYIuXXWA5zadXPWY6w | ||||||
|  | -> ssh-ed25519 KLPP8w BVp4rDkOYSQyn8oVeHFeinSqW+pdVtxBF9+5VM1yORY | ||||||
|  | bMwppAi8Nhz0328taU4AzUkTVyWtSLvFZG6c5W/Fs78 | ||||||
|  | --- xCbqLhXAcOziO2wmbjTiSQfZvt5Rlsc4SCvF+iEzpQA | ||||||
|  | ôKB£î/²ZÅÈrÙ%¾à4¡´—Mq5×Ô_ÌÂÝ’‹†ã„Ò11ܨqM;& ¢‡LríÂÒføû”]>N | ||||||
							
								
								
									
										7
									
								
								pkgs/agenix/example/armored-secret.age
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkgs/agenix/example/armored-secret.age
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | -----BEGIN AGE ENCRYPTED FILE----- | ||||||
|  | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFYzWG1FQSBpZkZW | ||||||
|  | aFpLNnJxc0VUMHRmZ2dZS0pjMGVENnR3OHd5K0RiT1RjRUhibFZBCnN5UG5vUjA3 | ||||||
|  | SXpsNGtiVUw4T0tIVFo5Wkk5QS9NQlBndzVvektiQ0ozc0kKLS0tIGxyY1Q4dEZ1 | ||||||
|  | VGZEanJyTFNta2JNRmpZb2FnK2JyS1hSVml1UGdMNWZKQXMKYla+wTXcRedyZoEb | ||||||
|  | LVWaSx49WoUTU0KBPJg9RArxaeC23GoCDzR/aM/1DvYU | ||||||
|  | -----END AGE ENCRYPTED FILE----- | ||||||
							
								
								
									
										9
									
								
								pkgs/agenix/example/passwordfile-user1.age
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								pkgs/agenix/example/passwordfile-user1.age
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | age-encryption.org/v1 | ||||||
|  | -> ssh-ed25519 KLPP8w s1DYZRlZuSsyhmZCF1lFB+E9vB8bZ/+ZhBRlx8nprwE | ||||||
|  | nmYVCsVBrX2CFXXPU+D+bbkkIe/foofp+xoUrg9DHZw | ||||||
|  | -> ssh-ed25519 V3XmEA Pwv3oCwcY0DX8rY48UNfsj9RumWsn4dbgorYHCwObgI | ||||||
|  | FKxRYkL3JHtJxUwymWDF0rAtJ33BivDI6IfPsfumM90 | ||||||
|  | -> V'v(/u$-grease em/Vgf 2qDuk | ||||||
|  | 7I3iiQLPGi1COML9u/JeYkr7EqbSLoU | ||||||
|  | --- 57WJRigUGtmcObrssS3s4PvmR8wgh1AOC/ijJn1s3xI | ||||||
|  | <EFBFBD>'K©Æ·Y&‘7GÆOÝòFj±kÆXç«BnuJöê:9Ê(’ÙÏX¬#¼AíÄÞÃÚ§j’,ê_ÈþÝ?ÝZ“¥vœ¹V’96]oks~%£c	Îe^CÅ%JQ5€<H¢z}îCý,°pŒ¿*!W§§ÈA±ºÒ…dC¼K)¿¢-žy | ||||||
							
								
								
									
										
											BIN
										
									
								
								pkgs/agenix/example/secret1.age
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pkgs/agenix/example/secret1.age
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5
									
								
								pkgs/agenix/example/secret2.age
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								pkgs/agenix/example/secret2.age
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | age-encryption.org/v1 | ||||||
|  | -> ssh-ed25519 V3XmEA OB4+1FbPhQ3r6iGksM7peWX5it8NClpXIq/o5nnP7GA | ||||||
|  | FmHVUj+A5i5+bDFgySQskmlvynnosJiWUTJmBRiNA9I | ||||||
|  | --- tP+3mFVtd7ogVu1Lkboh55zoi5a77Ht08Uc/QuIviv4 | ||||||
|  | ¤¬Xæ{”ïOŠ£èätMXxÔvÓª(¬IÁmyPÇï¸è+3²S3i | ||||||
							
								
								
									
										23
									
								
								pkgs/agenix/example/secrets.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								pkgs/agenix/example/secrets.nix
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | let | ||||||
|  |   user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH"; | ||||||
|  |   system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE"; | ||||||
|  | in | ||||||
|  | { | ||||||
|  |   "secret1.age".publicKeys = [ | ||||||
|  |     user1 | ||||||
|  |     system1 | ||||||
|  |   ]; | ||||||
|  |   "secret2.age".publicKeys = [ user1 ]; | ||||||
|  |   "passwordfile-user1.age".publicKeys = [ | ||||||
|  |     user1 | ||||||
|  |     system1 | ||||||
|  |   ]; | ||||||
|  |   "-leading-hyphen-filename.age".publicKeys = [ | ||||||
|  |     user1 | ||||||
|  |     system1 | ||||||
|  |   ]; | ||||||
|  |   "armored-secret.age" = { | ||||||
|  |     publicKeys = [ user1 ]; | ||||||
|  |     armor = true; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								pkgs/agenix/example_keys/system1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkgs/agenix/example_keys/system1
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | -----BEGIN OPENSSH PRIVATE KEY----- | ||||||
|  | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW | ||||||
|  | QyNTUxOQAAACDyQ8iK/xUs9XCXXKFuvUfja1s8Biv/t4Caag9bfC9sxAAAAJA3yvCWN8rw | ||||||
|  | lgAAAAtzc2gtZWQyNTUxOQAAACDyQ8iK/xUs9XCXXKFuvUfja1s8Biv/t4Caag9bfC9sxA | ||||||
|  | AAAEA+J2V6AG1NriAIvnNKRauIEh1JE9HSdhvKJ68a5Fm0w/JDyIr/FSz1cJdcoW69R+Nr | ||||||
|  | WzwGK/+3gJpqD1t8L2zEAAAADHJ5YW50bUBob21lMQE= | ||||||
|  | -----END OPENSSH PRIVATE KEY----- | ||||||
							
								
								
									
										1
									
								
								pkgs/agenix/example_keys/system1.pub
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pkgs/agenix/example_keys/system1.pub
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE | ||||||
							
								
								
									
										7
									
								
								pkgs/agenix/example_keys/user1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkgs/agenix/example_keys/user1
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | -----BEGIN OPENSSH PRIVATE KEY----- | ||||||
|  | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW | ||||||
|  | QyNTUxOQAAACC9InTb4BornFoLqf5j+/M8gtt7hY2KtHr3FnYxkFGgRwAAAJC2JJ8htiSf | ||||||
|  | IQAAAAtzc2gtZWQyNTUxOQAAACC9InTb4BornFoLqf5j+/M8gtt7hY2KtHr3FnYxkFGgRw | ||||||
|  | AAAEDxt5gC/s53IxiKAjfZJVCCcFIsdeERdIgbYhLO719+Kb0idNvgGiucWgup/mP78zyC | ||||||
|  | 23uFjYq0evcWdjGQUaBHAAAADHJ5YW50bUBob21lMQE= | ||||||
|  | -----END OPENSSH PRIVATE KEY----- | ||||||
							
								
								
									
										1
									
								
								pkgs/agenix/example_keys/user1.pub
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pkgs/agenix/example_keys/user1.pub
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH | ||||||
							
								
								
									
										23
									
								
								pkgs/agenix/update.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								pkgs/agenix/update.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | 
 | ||||||
|  | set -e | ||||||
|  | 
 | ||||||
|  | # All operations are done relative to root | ||||||
|  | GITROOT=$(git rev-parse --show-toplevel) | ||||||
|  | cd "$GITROOT" | ||||||
|  | 
 | ||||||
|  | REVISION=${1:-main} | ||||||
|  | 
 | ||||||
|  | TMPCLONE=$(mktemp -d) | ||||||
|  | trap "rm -rf ${TMPCLONE}" EXIT | ||||||
|  | 
 | ||||||
|  | git clone https://github.com/ryantm/agenix.git --revision="$REVISION" "$TMPCLONE" --depth=1 | ||||||
|  | 
 | ||||||
|  | cp "${TMPCLONE}/pkgs/agenix.sh" pkgs/agenix/agenix.sh | ||||||
|  | cp "${TMPCLONE}/pkgs/agenix.nix" pkgs/agenix/default.nix | ||||||
|  | sed -i 's#../example#./example#' pkgs/agenix/default.nix | ||||||
|  | 
 | ||||||
|  | cp "${TMPCLONE}/example/"* pkgs/agenix/example/ | ||||||
|  | cp "${TMPCLONE}/example_keys/"* pkgs/agenix/example_keys/ | ||||||
|  | 
 | ||||||
|  | cp "${TMPCLONE}/modules/age.nix" m/module/agenix.nix | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user