ryantm / agenix

age-encrypted secrets for NixOS and Home manager
https://matrix.to/#/#agenix:nixos.org
Creative Commons Zero v1.0 Universal
1.34k stars 108 forks source link

Is there any way to "post-process" a secret? #200

Closed charmoniumQ closed 7 months ago

charmoniumQ commented 9 months ago

This issue is easiest to explain in an example: Vaultwarden and Nextcloud both need to be able to log in to an SMTP server in order to send mail on their behalf. I pay for email service per use, so I'd like to use one login for both. However, the NixOS Vaultwarden module needs the password in a file like SMTP_PASSWORD=${password goes here (docs), whereas the NixOS Nextcloud module needs the password in a file like {"mail_smtppassword": "${password goes here}"}.

Is there a way I can store the password once in agenix and post-process it two ways? Otherwise, would I have to painstakingly override those NixOS modules? Is there another way I am not seeing?

charmoniumQ commented 9 months ago

I ended up writing some hacky activation scripts to do this, but I am still wondering if there is a better way.

stephank commented 9 months ago

I think activation scripts are the way. I ended up doing something like:

{ config, lib, ... }:

lib.mkIf (config.age.secrets != { }) {

  system.activationScripts.agenixCustom = lib.stringAfter "agenixChown" ''
    # Your extension here.
  '';

  # So scripts that depend on "agenix" also depend on the extension.
  system.activationScripts.agenix.deps = [ "agenixCustom" ];

}
nbraud commented 7 months ago

Does this need a solution specific to agenix?

For instance, one could use write (a module to generate) configuration snippets such as this:

systemd.paths.smtp_password = {
  wantedBy = [ "nextcloud.service" "vaultwarden.service" ];
  pathConfig.PathChanged = [ config.agenix.secrets.smtp.path ];
};
systemd.services.smtp_password = {
  serviceConfig.Type = "oneshot";
  script = ''
    set -euo pipefail
    PASSWORD="$(cat ${config.agenix.secrets.smtp.path})"
    echo "SMTP_PASSWORD=${PASSWORD}"                > /run/secrets/smtp/vaultwarden
    echo "{\"mail_smtppassword\": \"${PASSWORD}\"}" > /run/secrets/smtp/nextcloud
  '';
};
charmoniumQ commented 7 months ago

That's a good idea