Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support rules from flake output (nixosConfigurations) #86

Open
pinpox opened this issue Dec 27, 2021 · 10 comments
Open

Support rules from flake output (nixosConfigurations) #86

pinpox opened this issue Dec 27, 2021 · 10 comments

Comments

@pinpox
Copy link

pinpox commented Dec 27, 2021

Copy-pasting here from yaxitech/ragenix#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.

@ryantm
Copy link
Owner

ryantm commented Dec 28, 2021

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?

@pinpox
Copy link
Author

pinpox commented Dec 28, 2021

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

@iwanb
Copy link

iwanb commented Oct 15, 2022

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
            })
        ];

@robryk
Copy link

robryk commented Jan 31, 2023

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.

@pinpox
Copy link
Author

pinpox commented Jan 31, 2023

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.

@ryantm
Copy link
Owner

ryantm commented Jan 31, 2023

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
Copy link
Author

pinpox commented Feb 1, 2023

Pinpox they aren't proposing moving the config out of nixosConfigurations.

Oh sorry, I misunderstood then. Still interested in this feature btw.

@treed
Copy link

treed commented Apr 29, 2023

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?

@pinpox
Copy link
Author

pinpox commented May 8, 2023

Pulling config.age.secrets.*.file from a nixosSystem results 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.

@treed
Copy link

treed commented May 9, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants