Mic92 / sops-nix

Atomic secret provisioning for NixOS based on sops
MIT License
1.55k stars 141 forks source link

Nix darwin module #614

Open Mic92 opened 3 weeks ago

niklasravnsborg commented 3 weeks ago

@Mic92 I've tried to use this but for me it doesn't create the secrets in the defaultSymlinkPath and defaultSecretsMountPoint. For me it only created age-keys.txt and and empty sops-nix-secretfs file...


EDIT: I think this is because my SSH-key is password protected. I found out by running: cat /var/log/sops.log.

Mic92 commented 3 weeks ago

@Mic92 I've tried to use this but for me it doesn't create the secrets in the defaultSymlinkPath and defaultSecretsMountPoint. For me it only created age-keys.txt and and empty sops-nix-secretfs file...

EDIT: I think this is because my SSH-key is password protected. I found out by running: cat /var/log/sops.log.

password protected ssh keys are unfortunately nothing we can support, because sops runs early in boot, where we cannot prompt for passwords. I would suggest generating an age key for now.

niklasravnsborg commented 2 weeks ago

password protected ssh keys are unfortunately nothing we can support, because sops runs early in boot, where we cannot prompt for passwords. I would suggest generating an age key for now.

Thank you. My solution was to use your ssh-to-age program to generate the age key from my encrypted SSH key and store it locally, and it worked well :)

My problem now is that secrets aren't available immediately after logging in for other launchd services to consume. The secrets mount is only available after sops-install-secrets was run. On macOS, this gets triggered by the launchd daemon, and it might take a few seconds to decrypt the secrets and mount the in-memory volume.

In my use case, I have another launchd daemon that runs a service dependent on the decrypted secrets file. But this file is not available yet when the service is started. I only realized sops-nix is using a volume mount after tinkering with this module and the code a bit. Before that, I assumed that the secret files would just be replaced on disk when sops-install-secrets was run and that they would persist on reboot. In such a case, we wouldn't even need a launchd service and could only redecrypt the secret on "nixos / nix-darwin switch", but I see the need for an in-memory volume.

One solution might be to use wait4path /path/to/secret in the other services before they are run, but this would require overriding the launchd.daemons."some-service".command for the according services, which seems hacky and cumbersome.

For now, it feels like this might be the reason why I can't use sops-nix for my use case. @Mic92 Do you have some thoughts on that?

niklasravnsborg commented 1 week ago

UPDATE: In the end I used some scripting to restart my other service when the secret files are available: https://github.com/niklasravnsborg/dotfiles/commit/1afccc9c311f82d2e0cd8830141d94a158dba29a. A problem I encountered was that file watching doesn't quite work as expected for symbolic links to files inside of a volume that may not be yet mounted, when the file watcher is started. But my solution handles most cases fine.

Mic92 commented 1 week ago

@niklasravnsborg do you have a clue how I could make error reporting better in the darwin activation phase? launchd just silently fails, which is not great. I was wondering if I should not just run sops-install-secrets additionally in foreground on updates.

niklasravnsborg commented 1 week ago

Which errors did you encounter? The /bin/launchctl bootstrap in the activation might not work because of the wrong path as I mentioned in a previous comment.

I guess it's fine to have it either restart the daemon or run the sops-install-secrets on activation but not do both.

Mic92 commented 1 week ago

I mean if the service fails, I want to see the error in the shell that runs launchd service.

niklasravnsborg commented 1 week ago

I see, yeah this makes it harder to debug sometimes. I think seeing errors in the shell that bootstraps the service is not what launchd is made for, since launchd services run in the context of the system in the background (similarily to what systemd does on linux). On bootstraping they are just scheduled for starting and there is no immediate feedback.

So I guess we could just run the launchd service on boot but use the sops-install-secrets script directly in the activation. There it doesn't have to trigger the launchd service again.

I found sudo launchctl print system/org.nixos.sops-nix quite useful for debugging and looking at the logs.

niklasravnsborg commented 1 week ago

@Mic92 Just an update on my comment: The PR on nix-darwin has now been merged: https://github.com/LnL7/nix-darwin/pull/1052 and it now makes sense to update the sops-nix invocation to use command instead of serviceConfig.Program. This will ensure, that the nix store is mounted and available before trying to launch the sops-nix script.

Mic92 commented 1 week ago

Thanks for the heads up