Description
I’ve setup sops-nix in my flakes NixOS configuration. I can access secrets from my NixOS configuration files. How do I access a secret from Home Manager without having to pass in the --impure
option?
Accessing SOPS Secrets via Home Manager
The Home Manager file that needs access to a secret:
{ config, osConfig, pkgs, ... }: {
home = {
packages = with pkgs; [ element-desktop ];
file."${config.xdg.userDirs.documents}/Secrets/Element/security-key.txt".source = osConfig.sops.secrets."app/element-desktop/message-key".path;
};
}
Current version of the above file here.
This works when I rebuild my system with sudo nixos-rebuild switch --flake ./ --impure
, however, I’d like to pass in the value(s) in sops.secrets...
into Home Manager via my flake.nix
file so Nix knows that it’s an external dependency (and presumably will not require the use of --impure
).
Stripped Down Version of My flake.nix
{
inputs = {
...
sops-nix.url = "github:Mic92/sops-nix";
};
outputs = inputs@{ self, home-manager, nixpkgs, sops-nix, ... }: {
nixosConfigurations.<hostName> = inputs.nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs pkgs; };
modules = [
home-manager.nixosModules.home-manager
<pathToNixOsConfig> <----- This would be the NixOS file that
{ \---- configures sops-nix and currently
home-manager = { \--- accessed secrets w/o the --impure option.
extraSpecialArgs = { inherit inputs pkgs; };
users.<userName>.imports = [
<pathToUserHomeManagerConfig> <----- This would be the Home
]; \---- Manager file that is
}; \--- attempting to access
} \-- the sops secret.
];
};
};
}
Real flake.nix
file here.
Note(s)
Here is my full NixOS + Home Manager configuration.
In your home-manager flake user imports add inputs.sops-nix.homeManagerModule
.
Then in your HM configuration file add:
{
sops-nix,
...
}:{
sops = {
age.keyFile = ...
defaultSopsFile = ...
};
<config>
}
Hopefully that works for you!
The Good
It imported sops-nix
and config.sops.secrets.<bla>
exist.
The Bad
The path that’s returned is incorrect. Specificly, it’s %r/secrets/app/element-desktop/message-key
when it should be /run/user/1000/secrets/app/element-desktop/message-key
(because it’s a Home Manager modules rather than a NixOS one).
The Ugly
There exists no /run/user/1000/secrets/
directory, so the path is wrong, but even if it was correct, it doesn’t exist. It also doesn’t exist in the location it would be at if it was configured as a NixOS module (/run/secrets/app/element-desktop/message-key
).
New Home Manager File
{ config, pkgs, sops-nix, user, ... }: {
sops = {
defaultSopsFile = <pathToSecretsYamlFile>;
defaultSopsFormat = "yaml";
age.keyFile = <pathToSopsAgeKeysFile>;
secrets."app/element-desktop/message-key" = { };
};
home = {
packages = with pkgs; [ element-desktop ];
file."${config.xdg.userDirs.documents}/Secrets/Element/security-key.txt".source = config.sops.secrets."app/element-desktop/message-key".path;
};
}
Note
When I change .source
to .text
it writes this %r/secrets/app/element-desktop/message-key
to the file and /run/user/1000/secrets/
still don’t exist.
Error Output
error:
… while calling the 'head' builtin
at /nix/store/5hwz775f3grzikafj1sbwx4lqkjwqswb-source/lib/attrsets.nix:922:11:
921| || pred here (elemAt values 1) (head values) then
922| head values
| ^
923| else
… while evaluating the attribute 'value'
at /nix/store/5hwz775f3grzikafj1sbwx4lqkjwqswb-source/lib/modules.nix:807:9:
806| in warnDeprecation opt //
807| { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
| ^
808| inherit (res.defsFinal') highestPrio;
(stack trace truncated; use '--show-trace' to show the full trace)
error: A definition for option `home-manager.users.reedclanton.home.file."/home/reedclanton/Documents/Secrets/Element/security-key.txt".source' is not of type `path'. Definition values:
- In `/nix/store/z1ggqi8k3xhgcwc32702m2glhkr4k7qm-source/users/reedclanton/home/modules/applications/gui/element-desktop.nix': "%r/secrets/app/element-desktop/message-key"
I think it needs to be something like:
sops.secrets.element-message-key = {};
home = {
file."${config......" = config.sops.secrets.element-message-key.path;
};
And then your file contents in the secrets file set something like:
element-message-key: |
abcdefgh12345
Unfortunately, no luck. The value changes, but only to mach the new name (i.e. %r/secrets/app-element-desktop-message-key
rather than %s/secrets/app/element-desktop/message-key
).
Also, the same value I had works when I use --impure
(as described in the original post), so I don’t think it’s an issue associated with how the secrets key is formatted. Plus, that secrets file has multiple other secrets in it that are currently functioning in the NixOS portion of the configuration.
Sorry, I’m running up against the end of my knowledge! I don’t see why you’re not getting the files created in /run/user/1000/secrets
.
Don’t be sorry! Thanks for the help. I learned some about importing modules from your responses.
Perhaps the issue relate to how sops-nix is imported. Maybe importing both NixOS and Home Manager modules system wide (i.e. from the flake) causes a conflict.
Still haven’t solved this. Suggestions welcome.
FWIW I’m having the ame issue - did you ever solve this?
Unfortunately no. I’ve just been using the NixOS module in Home Manager. This requires that --impure
be passed in (and is ugly and I hate it).
Hey, I actually was able to work around it. There’s a github issue for this from a while back, and it seems the solution is to append the following options to your sops config:
sops = {
# ... all the other stuff ...
defaultSymlinkPath = "/run/user/1000/secrets";
defaultSecretsMountPoint = "/run/user/1000/secrets.d";
};
Reason being that sops-nix
apparently has no way of knowing your UUID at build time. (I’m not really happy with this solution because I would rather not hardcode the UUID, if you happen to know a way around that, please do tell!)
Hope this is helpful!