I’m struggling to find a way to securely pass a secret value located in /run/secrets/my-secret (generated using sops-nix) to a nixos option that expects a string. It seems simple but I can’t figure it out.
Generally there would be a service option that allows the use of a file that contains the sensitive data like “services.guacamole-client.settings.ldap-search-bind-passwordFile” but it doesn’t exists for this service. Does anyone have any ideas how I would go about passing the value in “/run/secrets/my-secret” to the ldap-search-bind-password option?
P.S - I’m running flakes so I can’t use builtins.readFile unfortunately…
If the module isn’t written in a way that would allow reading the secret from a file, then you have to dig the modules implementation if you can work around it by other means, and in the worst case you have to completely set up the service by hand, taking appropriate measures to get the secret where its needed by reading at runtime or using templates.
In an effort to take the generated guacamole.properties file that the nixos option produces and append "ldap-search-bind-password = “secret-value” to the end of it but the final-config derivation complains that it can’t find the secrets path since it’s isolated in the sandbox environment.
That whole approach is an invalid way to handle secrets since it would put them in the nix store if it had succeeded. Everything in the nix store is world-readable. Secrets must be handled at activation/run time, not build time, in order to avoid this.
As far as I can tell though there isn’t any way to pass that value during runtime since the /etc/guacamole/guacamole.properties file is generated during the build time and I can’t modify it afterwards.
You could set environment.etc."guacamole/guacamole-properties".enable = false; and then create the file at runtime with an activation snippet or a systemd oneshot service. The script that creates it can directly access the (now-unused) config.environment.etc."guacamole/guacamole-properties".source file as an input making that script the only actual reference to that file in your config, and grab the secret from wherever sops puts it, splicing it in and placing the result in /etc.
It creates a copy of the final guacamole.properties file during runtime and appends the contents of the password file and places the new config back to the original location.
That turned out pretty close to what I was suggesting, except that:
It’s possible for the secret-less config file to appear in /etc depending on race conditions.
It’s possible to add the secret multiple times… which may or may not be a problem.
The etc activation snippet and your oneshot service are fighting for control of the same file.
I would still set environment.etc."guacamole/guacamole-properties".enable = false; (you may need to lib.mkForce that, not sure) to stop the etc activation script from actually adding the file, and change
So the oneshot service pulls the pristine config file the module created directly from the nix store each time. Less stateful and more robust, overall.
Regardless, your solution as it is properly secures the secret, which is the main criteria.
Hmm if I set environment.etc."guacamole/guacamole-properties".enable = false; wouldn’t that make the service fail since it would be trying to copy over a non-existent file?
I did end up setting cp ${config.environment.etc."guacamole/guacamole-properties".source} $temp_conf though I agree it keeps things more stateless which is always nice.
I don’t see how. The service would be the thing responsible for creating the file. The value of config.environment.etc."guacamole/guacamole-properties".source would be unaffected by setting the enable = false;, if that’s what you mean. The normal /etc management machinery would ignore all the settings in environment.etc."guacamole/guacamole-properties", but they would still have their values.
Hmm yeah you’re right adding that line didn’t seem to have any effect on the one-shot service.
My understanding seemed to be incorrect and everything seems to be working as expected now with the added benefits of no race conditions or multiple processes fighting for control over the guacamole.properties file.