Support rules from flake output (nixosConfigurations)
Copy-pasting here from https://github.com/yaxitech/ragenix/issues/52
Just an idea I wanted to propose:
Would it be possible to support reading rules from another flake's output instead of a separate secrets.nix file?
E.g. If I have a flake defining my systems like this:
{
outputs = { self, nixpkgs }: {
nixosConfigurations = {
system1 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ pkgs, ... }:
{
# Config ...
age.option-to-set-key = "ssh-ed25519 AAAAAAA...";
age.secrets.secret1.file = ./secrets/secret1.age;
age.secrets.secret2.file = ./secrets/secret2.age;
})
];
};
system2 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ pkgs, ... }:
{
# Config
age.option-to-set-key = "ssh-ed25519 AAAABBB...";
age.secrets.secret2.file = ./secrets/secret2.age;
})
];
};
};
};
}
nixosConfigurations could be used directly resulting in a rule set equivalent to:
let
system1 = "ssh-ed25519 AAAAAAA..";
system2 = "ssh-ed25519 AAAABBB..";
in
{
"secret1.age".publicKeys = [ system1 ];
"secret2.age".publicKeys = [ system1 system2];
}
Since you plan on supporting flakes it seems like an extra step to have to write a secrets.nix file, as the information is already present in an organized form.
On the one hand this is cool because it would mean one less file and possibly quicker setup. On the other, it means we'd have to evaluate all the nixosConfigurations to manipulate secrets.
Where would you specify what users have access to the secrets?
Where would you specify what users have access to the secrets?
Couldn't it be just an option at the same level as .file?
system2 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ pkgs, ... }:
{
# Config
age.option-to-set-key = "ssh-ed25519 AAAABBB...";
age.secrets.secret2.file = ./secrets/secret2.age;
age.secrets.secret2.user = "user1";
age.secrets.secret2.group = "mygroup";
age.secrets.secret2.mode = "644";
})
];
};
Was just the first that came to mind, I might have missed implications here
Could the opposite be possible? I.e. refer to secrets.nix from the configuration so it's automatically populated? E.g. like an utility function:
modules = [
({ pkgs, ... }:
{
# Config ...
age.secrets = agenix.from-secrets ./secrets/secrets.nix
})
];
Why can't we instead look for some other flake output? For example, have an option to evaluate .#agenixSecrets instead of secrets.nix. That way, it's up to whoever writes the flake how that is defined and what else needs to be evaluated on the way to evaluating that.
Why can't we instead look for some other flake output
Having them inside the nixosConfigurations would make them more self-contained, whcih is nice for things like building them in a CI. For example I run the following inside a CI:
nix build -L '.#nixosConfigurations.birne.config.system.build.toplevel'
This makes sure everything is build (and cached) and working before the configuration is actually applied to the host.
That's a fine idea robryk.
Pinpox they aren't proposing moving the config out of nixosConfigurations. They're proposing moving the agenix CLI config into the flake.
Pinpox they aren't proposing moving the config out of nixosConfigurations.
Oh sorry, I misunderstood then. Still interested in this feature btw.
I decided to see if I could implement something like this, and immediately ran into an issue:
Pulling config.age.secrets.*.file from a nixosSystem results in paths that are in the nix store, rather than local to the repo. I could maybe refactor my flake to have an attrset of the bare config before it gets passed through nixosSystem, but I think the resulting brittleness would cause even more issues down the road.
Anyone have any suggestions?
Pulling
config.age.secrets.*.filefrom anixosSystemresults in paths that are in the nix store
Only if the path is of type path. You can define them as strings without problems, I do that for my deployment tool. The option looks like this and can be used in nixosConfigurations like this.
I think that'd require changes in agenix itself to work correctly; although possibly just in the option types.
Unless I'm reading this incorrectly it seems to also be the path as deployed on the system, rather than the path relative to where secrets.nix would typically be found (I guess where flake.nix is, in my scenario.)
It seems possible have the file attribute be a string as with your case, but my understanding is that the secrets get deployed to the hosts as implicit dependencies of the activation script, by interpolation as store paths. So unless there's something else happening here (which seems entirely possible, but if so I'm unsure how to find it), using local paths as strings would break deployment.
I could maybe do it by adding a secondary file option, where one is a path for deployment and another is a string for local configuration. I'm not sure that's a strong improvement over the current state, though.
Is it possible to have a string (referencing a local path) that can be converted into a path? Since the other direction results in the full store path. Maybe I'll see if I can make that work.