Claude eventually helped me find a more pleasant solution based on extraSpecialArgs . I've tried to minimize it for clarity.
The initial goal was to create a self-contained, minimal flake.nix that integrated nix-darwin, home-manager, and agenix. The desired end state is a macOS system with an agenix-encrypted secret decrypted and stored at ~/secret1.txt (by home-manager).
The following flake.nix breaks the configuration into 2 sections:
homeconfig : to configure home-manager
configuration : to configure nix-darwin
The secrets are defined in configuration then shuttled to homeconfig via extraSpecialArgs.darwinSecrets . The path to the secret is then leveraged by homeconfig to populate ~/secret1.txt (i.e., home.file."secret1.txt".source = config.lib.file.mkOutOfStoreSymlink darwinSecrets.secret1; ). Importantly, this circumvents the following error that would arise if the secret path was accessed directly (i.e., home.file."secret1.txt".source = config.age.secrets.secret1.path; ):
error: A definition for option `home-manager.users.andrew.home.file."secret1.txt".source' is not of type `absolute path'. Definition values:
- In `<unknown-file>': "$(getconf DARWIN_USER_TEMP_DIR)/agenix/secret1"
If any Nix experts observe any flaws in this approach, please raise them now. Otherwise, I hope it helps:
{
description = "nix-darwin & home-manager & agenix";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/master";
nix-darwin.url = "github:nix-darwin/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
agenix.url = "github:ryantm/agenix";
};
outputs = inputs @ { self, nix-darwin, nixpkgs, home-manager, agenix, ... }:
let
homeconfig = { pkgs, config, lib, darwinSecrets, ... }: {
imports = [agenix.homeManagerModules.default];
home.file."secret1.txt".source = config.lib.file.mkOutOfStoreSymlink darwinSecrets.secret1;
home.stateVersion = "25.05";
home.packages = with pkgs; [agenix.packages.aarch64-darwin.default];
programs.home-manager.enable = true;
};
configuration = { pkgs, config, lib, ... }: {
age = {
secrets = {
secret1 = {
symlink = true;
file = ./secret1.age;
mode = "777";
};
};
};
environment.systemPackages = [agenix.packages.aarch64-darwin.default];
home-manager = {
useGlobalPkgs = true;
users.andrew = homeconfig;
useUserPackages = true;
extraSpecialArgs = {
darwinSecrets = {
secret1 = config.age.secrets.secret1.path;
};
};
};
nix.settings.experimental-features = "nix-command flakes";
nixpkgs.hostPlatform = "aarch64-darwin";
system = {
configurationRevision = self.rev or self.dirtyRev or null;
stateVersion = 5;
};
};
in
{
darwinConfigurations."mac-book-pro" = nix-darwin.lib.darwinSystem {
modules = [
agenix.darwinModules.default
configuration
home-manager.darwinModules.home-manager
];
};
};
}
|