Im trying to configure sops but it fails to start.
❯ systemctl --user status sops-nix.service
○ sops-nix.service - sops-nix activation
Loaded: loaded (/home/felipepinto/.config/systemd/user/sops-nix.service; enabled; preset: ignored)
Active: inactive (dead) since Thu 2025-02-20 13:07:42 WET; 29min ago
Invocation: 8e8e503234044545a586ba41acfab11e
Process: 2005 ExecStart=/nix/store/lp7lnzws9sl3k6ysqk30y5xv89a256fh-sops-nix-user (code=exited, status=1/FA>
Main PID: 2005 (code=exited, status=1/FAILURE)
Mem peak: 25.6M
CPU: 19ms
fev 20 13:07:42 gmktecK8 systemd[1985]: Starting sops-nix activation...
fev 20 13:07:42 gmktecK8 lp7lnzws9sl3k6ysqk30y5xv89a256fh-sops-nix-user[2005]: generating machine-specific age key...
fev 20 13:07:42 gmktecK8 lp7lnzws9sl3k6ysqk30y5xv89a256fh-sops-nix-user[2013]: /nix/store/wdap4cr3bnm685f27y9bb6q5b6q18msl-coreutils-9.5/bin/mkdir: cannot create directory ‘/var/lib/sops-nix’: Permission denied
fev 20 13:07:42 gmktecK8 lp7lnzws9sl3k6ysqk30y5xv89a256fh-sops-nix-user[2020]: age-keygen: error: failed to open output file "/var/lib/sops-nix/key.txt": open /var/lib/sops-nix/key.txt: no such file or directory
fev 20 13:07:42 gmktecK8 lp7lnzws9sl3k6ysqk30y5xv89a256fh-sops-nix-user[2020]: age-keygen: report unexpected or unhelpful errors at https://filippo.io/age/report
fev 20 13:07:42 gmktecK8 lp7lnzws9sl3k6ysqk30y5xv89a256fh-sops-nix-user[2029]: Cannot read ssh key '/etc/ssh/ssh_host_ed25519_key': open /etc/ssh/ssh_host_ed25519_key: permission denied
fev 20 13:07:42 gmktecK8 lp7lnzws9sl3k6ysqk30y5xv89a256fh-sops-nix-user[2029]: /nix/store/5l7m96290y8546fx7803i23v4lldfwd9-sops-install-secrets-0.0.1/bin/sops-install-secrets: cannot read keyfile '/var/lib/sops-nix/key.txt': open /var/lib/sops-nix/key.txt: no such file o>
fev 20 13:07:42 gmktecK8 systemd[1985]: sops-nix.service: Main process exited, code=exited, status=1/FAILURE
fev 20 13:07:42 gmktecK8 systemd[1985]: sops-nix.service: Failed with result 'exit-code'.
fev 20 13:07:42 gmktecK8 systemd[1985]: Failed to start sops-nix activation.
~
i configured sops like this:
{ lib, config, inputs, pkgs, ... }:
{
imports = [ inputs.sops-nix.nixosModules.sops ];
options.modules.security.sops.enable =
lib.mkEnableOption "enable sops module";
config = lib.mkIf config.modules.security.sops.enable {
environment.systemPackages = [ pkgs.sops ];
sops = {
defaultSopsFormat = "yaml";
# This will add secrets.yml to the nix store
# You can avoid this by adding a string to the full path instead, i.e.
# defaultSopsFile = ../../../secrets/secrets.yaml;
defaultSopsFile = "/root/.sops/secrets/secrets.yaml";
# defaultSopsFile = ./secrets/example.yaml;
# This will automatically import SSH keys as age keys
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
# This is using an age key that is expected to already be in the filesystem
age.keyFile = "/var/lib/sops-nix/key.txt";
# This will generate a new key if the key specified above does not exist
age.generateKey = true;
};
};
}
Do you have ssh enabled? Does it use/create the key you want to use in sops?
i do on my nixos configuration, or at least i believe i do? how should i check?
this is my openssh.nix module
{ lib, config, ... }:
{
options.modules.security.openssh.enable =
lib.mkEnableOption "enable openssh module";
config = lib.mkIf config.modules.security.openssh.enable {
services.openssh = {
enable = true;
startWhenNeeded = true; # systemd will start an instance for each incoming connection
settings.PermitRootLogin = "no";
settings.PasswordAuthentication = false; # require public key authentication
hostKeys = [
{
comment = "${config.networking.hostName}.local";
path = "/etc/ssh/ssh_host_ed25519_key";
rounds = 64;
type = "ed25519";
}
];
};
};
}
Just to make sure: you enabled that module n your config as well, right?
Can you check if the key file exists on your system?
yup the host ssh key is there alright. and yeah double checked the module on my config, its enabled
Oh I did not read the error carefully enough. It complains that you don’t have permission to access the ssh keys.
Are you using a home-manager stand alone config?
yeah i am using the standalone
i made sure to add my personal home key to .sops.yaml
file
Then you can’t use the ssh keys (at least not the system ones) for decryption. That only works when you use it as a NixOS home-manager module because the activation script is run as root.
You should then use your users age key as stated in the documentation: GitHub - Mic92/sops-nix: Atomic secret provisioning for NixOS based on sops
i tried to follow that tho, i have both my computer host key that was generated and my personal ssh key both converted to age added to the file .sops.yaml
, they should both be able to decrypt files no?
But you are using the global ones which are only readable or writable (in case of the age key) by root. If you are using stand alone home-manager you should use ones that are readable by your user like in the example of the documentation I posted above:
age.keyFile = "/home/user/.age-key.txt"; # must have no password!
oh i think i understand, ok so how should i do this?
how can i config so that nixos can use the host key to decrypt its secrets and home-manager can use its home key to decrypt its own secrets?
You need to configure them separately. In the NixOS configuration you should be able to use the above configuration.
In your home-manager configuration you need to then reference just the key in your users home directory.
Ok, here it goes, i changed both sops.nix files for my home and host configurations:
this is /modules/home/sops.nix
{ lib, config, inputs, userName, ... }:
{
imports = [
inputs.sops-nix.homeManagerModules.sops
];
config = {
sops = {
# validateSopsFiles = false;
defaultSopsFormat = "yaml";
# This will add secrets.yml to the nix store
# You can avoid this by adding a string to the full path instead, i.e.
defaultSopsFile = ../../../secrets/default.yaml;
age = {
# This will automatically import SSH keys as age keys
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ];
# This is using an age key that is expected to already be in the filesystem
keyFile = "${config.home.homeDirectory}/.config/sops/age/key.txt";
# This will generate a new key if the key specified above does not exist
generateKey = true;
};
# secrets = {
# "private_keys/${userName}" = {
# path = "$HOME/.ssh/id_ed25519";
# };
# };
};
};
}
this is my modules/core/security/sops.nix
file
{ lib, config, inputs, pkgs, ... }:
{
imports = [ inputs.sops-nix.nixosModules.sops ];
options.modules.security.sops.enable =
lib.mkEnableOption "enable sops module";
config = lib.mkIf config.modules.security.sops.enable {
environment.systemPackages = [ pkgs.sops ];
sops = {
# validadeSopsFiles = false;
defaultSopsFormat = "yaml";
# This will add secrets.yml to the nix store
# You can avoid this by adding a string to the full path instead, i.e.
defaultSopsFile = "../../../secrets/secrets.yaml";
# defaultSopsFile = ./secrets/example.yaml;
age = {
# This will automatically import SSH keys as age keys
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
# This is using an age key that is expected to already be in the filesystem
keyFile = "/var/lib/sops-nix/key.txt";
# This will generate a new key if the key specified above does not exist
generateKey = true;
};
};
};
}
im still getting the error i showed above, i believe i followed the indications alright, on home everything is pointing to my home directory where the key is located alright. still when i run systemd… the first error that appears is that its failing the command mkdir /var/lib/sops-nix
i believe the first error has more to do with the core configuration than with home. but then idk why its having trouble afterall i run the nixos-rebuild switch
with sudo
Do you have your complete config online somewhere?
I just tried to access you config but it requires me to log in to gitlab. Is it a private repo?
2 Likes
Im sorry, i had fully forgotten i had made it private. Its back public now.
At a quick glance I don’t see any major issue. Would you mind running just the home-manager one again and post the complete error?
After some changes trying to fix stuff, i noticed it was not pointing to the email.yaml
file anymore so i had to fix it before trying to build again.
after the new fixes this is the error given:
error:
… from call site
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:45:18:
44| withExtraAttrs = rawModule:
45| let module = moduleChecks rawModule;
| ^
46| in {
… while calling 'moduleChecks'
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:32:18:
31|
32| moduleChecks = raw:
| ^
33| showWarnings (let
… from call site
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:33:5:
32| moduleChecks = raw:
33| showWarnings (let
| ^
34| failed = collectFailed raw.config;
… while calling 'showWarnings'
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:15:18:
14|
15| showWarnings = res:
| ^
16| let f = w: x: builtins.trace "warning: ${w}" x;
… from call site
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:17:8:
16| let f = w: x: builtins.trace "warning: ${w}" x;
17| in fold f res res.config.warnings;
| ^
18|
… while calling 'foldr'
at /nix/store/593xvgv994xlkm5mb7w4p1xxnzrs9wv6-source/lib/lists.nix:122:20:
121| */
122| foldr = op: nul: list:
| ^
123| let
… from call site
at /nix/store/593xvgv994xlkm5mb7w4p1xxnzrs9wv6-source/lib/lists.nix:129:8:
128| else op (elemAt list n) (fold' (n + 1));
129| in fold' 0;
| ^
130|
… while calling 'fold''
at /nix/store/593xvgv994xlkm5mb7w4p1xxnzrs9wv6-source/lib/lists.nix:125:15:
124| len = length list;
125| fold' = n:
| ^
126| if n == len
… while evaluating a branch condition
at /nix/store/593xvgv994xlkm5mb7w4p1xxnzrs9wv6-source/lib/lists.nix:126:9:
125| fold' = n:
126| if n == len
| ^
127| then nul
… while calling the 'length' builtin
at /nix/store/593xvgv994xlkm5mb7w4p1xxnzrs9wv6-source/lib/lists.nix:124:13:
123| let
124| len = length list;
| ^
125| fold' = n:
… while calling the 'throw' builtin
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:39:7:
38| else
39| throw ''
| ^
40|
… while calling the 'concatStringsSep' builtin
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:35:19:
34| failed = collectFailed raw.config;
35| failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed);
| ^
36| in if failed == [ ] then
… while calling anonymous lambda
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:35:47:
34| failed = collectFailed raw.config;
35| failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed);
| ^
36| in if failed == [ ] then
… from call site
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:35:55:
34| failed = collectFailed raw.config;
35| failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed);
| ^
36| in if failed == [ ] then
… while calling anonymous lambda
at /nix/store/cx1ca0rhmn6wwb93cpln8f9143bjs1wn-source/modules/default.nix:13:10:
12| collectFailed = cfg:
13| map (x: x.message) (filter (x: !x.assertion) cfg.assertions);
| ^
14|
… while evaluating the attribute 'message'
at /nix/store/vxisbcsmzkx7wj4i1cvsx9xs69kn4lfx-source/modules/home-manager/sops.nix:331:15:
330| assertion = builtins.pathExists secret.sopsFile;
331| message = "Cannot find path '${secret.sopsFile}' set in sops.secrets.${lib.strings.escapeNixIdentifier name}.sopsFile";
| ^
332| }
error: access to absolute path '/nix/store/secrets' is forbidden in pure evaluation mode (use '--impure' to override)
Is it possible that you use one too much ../
?