Loading nixos/doc/manual/release-notes/rl-2605.section.md +2 −0 Original line number Diff line number Diff line Loading @@ -308,3 +308,5 @@ See <https://github.com/NixOS/nixpkgs/issues/481673>. ``` **Do not set this globally!** This makes your setup inherently less secure. - `services.radicle` now supports importing the private key and passphrase as systemd creds. nixos/lib/systemd-unit-options.nix +0 −4 Original line number Diff line number Diff line Loading @@ -3,12 +3,8 @@ let inherit (systemdUtils.lib) assertValueOneOf automountConfig checkUnitConfig makeJobScript mountConfig serviceConfig unitConfig unitNameType ; Loading nixos/modules/services/misc/radicle.nix +49 −20 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ config, lib, pkgs, utils, ... }: let Loading @@ -15,6 +16,11 @@ let RAD_HOME = HOME; }; credentials = { privateKey = "xyz.radicle.node.secret"; privateKeyPassphrase = "xyz.radicle.node.passphrase"; }; # Convenient wrapper to run `rad` in the namespaces of `radicle-node.service` rad-system = pkgs.writeShellScriptBin "rad-system" '' set -o allexport Loading Loading @@ -131,16 +137,34 @@ in services.radicle = { enable = lib.mkEnableOption "Radicle Seed Node"; package = lib.mkPackageOption pkgs "radicle-node" { }; privateKeyFile = lib.mkOption { # Note that a key encrypted by systemd-creds is not a path but a str. type = with lib.types; either path str; privateKey = lib.mkOption { type = with lib.types; nullOr (either path str); default = null; description = '' Absolute file path to an SSH private key, An SSH private key (as an absolute file path or Systemd credential name), usually generated by `rad auth`. If it contains a colon (`:`) the string before the colon is taken as the credential name and the string after as a path encrypted with `systemd-creds`. If set to the default value of `null`, radicle will import the private key from a credential named `${credentials.privateKey}`. If configured as a credential name it will be imported via `ImportCredential=` in the service configuration. Refer to the systemd-creds documentation for more details <https://systemd.io/CREDENTIALS/> ''; }; privateKeyPassphrase = lib.mkOption { type = with lib.types; nullOr str; default = null; description = '' A passphrase for an SSH private key (as a Systemd credential name), usually provided on generation of the key with `rad auth`. If set to the default value of `null`, radicle will optionally import the passphrase from a credential named `${credentials.privateKeyPassphrase}`. If the passphrase is not set, radicle will prompt for it. If configured as a credential name it will be imported via `ImportCredential=` in the service configuration. Refer to the systemd-creds documentation for more details <https://systemd.io/CREDENTIALS/> ''; }; publicKey = lib.mkOption { Loading Loading @@ -304,23 +328,28 @@ in # Give only access to the private key to radicle-node. { serviceConfig = let keyCred = builtins.split ":" "${cfg.privateKeyFile}"; in if lib.length keyCred > 1 then if cfg.privateKey == null then { LoadCredentialEncrypted = [ cfg.privateKeyFile ]; # Note that neither %d nor ${CREDENTIALS_DIRECTORY} works in BindReadOnlyPaths= BindReadOnlyPaths = [ "/run/credentials/radicle-node.service/${lib.head keyCred}:${env.RAD_HOME}/keys/radicle" ]; ImportCredential = [ credentials.privateKey ]; } else if lib.types.path.check cfg.privateKey then { LoadCredential = [ "${credentials.privateKey}:${cfg.privateKey}" ]; } else { LoadCredential = [ "radicle:${cfg.privateKeyFile}" ]; BindReadOnlyPaths = [ "/run/credentials/radicle-node.service/radicle:${env.RAD_HOME}/keys/radicle" ]; ImportCredential = [ "${cfg.privateKey}:${credentials.privateKey}" ]; }; } { serviceConfig = if cfg.privateKeyPassphrase == null then { ImportCredential = [ credentials.privateKeyPassphrase ]; } else { ImportCredential = [ "${cfg.privateKeyPassphrase}:${credentials.privateKeyPassphrase}" ]; }; } ]; Loading nixos/tests/radicle-ci-broker.nix +4 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ in meta.maintainers = with lib.maintainers; [ defelo ]; nodes.seed = { virtualisation.credentials = { "xyz.radicle.node.secret".source = "${seed-ssh-keys.snakeOilEd25519PrivateKey}"; }; services.radicle = { enable = true; privateKeyFile = seed-ssh-keys.snakeOilEd25519PrivateKey; publicKey = seed-ssh-keys.snakeOilEd25519PublicKey; node.openFirewall = true; settings = { Loading nixos/tests/radicle.nix +4 −1 Original line number Diff line number Diff line Loading @@ -76,9 +76,12 @@ in { imports = [ commonHostConfig ]; virtualisation.credentials = { "xyz.radicle.node.secret".source = "${seed-ssh-keys.snakeOilEd25519PrivateKey}"; }; services.radicle = { enable = true; privateKeyFile = seed-ssh-keys.snakeOilEd25519PrivateKey; publicKey = seed-ssh-keys.snakeOilEd25519PublicKey; node = { openFirewall = true; Loading Loading
nixos/doc/manual/release-notes/rl-2605.section.md +2 −0 Original line number Diff line number Diff line Loading @@ -308,3 +308,5 @@ See <https://github.com/NixOS/nixpkgs/issues/481673>. ``` **Do not set this globally!** This makes your setup inherently less secure. - `services.radicle` now supports importing the private key and passphrase as systemd creds.
nixos/lib/systemd-unit-options.nix +0 −4 Original line number Diff line number Diff line Loading @@ -3,12 +3,8 @@ let inherit (systemdUtils.lib) assertValueOneOf automountConfig checkUnitConfig makeJobScript mountConfig serviceConfig unitConfig unitNameType ; Loading
nixos/modules/services/misc/radicle.nix +49 −20 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ config, lib, pkgs, utils, ... }: let Loading @@ -15,6 +16,11 @@ let RAD_HOME = HOME; }; credentials = { privateKey = "xyz.radicle.node.secret"; privateKeyPassphrase = "xyz.radicle.node.passphrase"; }; # Convenient wrapper to run `rad` in the namespaces of `radicle-node.service` rad-system = pkgs.writeShellScriptBin "rad-system" '' set -o allexport Loading Loading @@ -131,16 +137,34 @@ in services.radicle = { enable = lib.mkEnableOption "Radicle Seed Node"; package = lib.mkPackageOption pkgs "radicle-node" { }; privateKeyFile = lib.mkOption { # Note that a key encrypted by systemd-creds is not a path but a str. type = with lib.types; either path str; privateKey = lib.mkOption { type = with lib.types; nullOr (either path str); default = null; description = '' Absolute file path to an SSH private key, An SSH private key (as an absolute file path or Systemd credential name), usually generated by `rad auth`. If it contains a colon (`:`) the string before the colon is taken as the credential name and the string after as a path encrypted with `systemd-creds`. If set to the default value of `null`, radicle will import the private key from a credential named `${credentials.privateKey}`. If configured as a credential name it will be imported via `ImportCredential=` in the service configuration. Refer to the systemd-creds documentation for more details <https://systemd.io/CREDENTIALS/> ''; }; privateKeyPassphrase = lib.mkOption { type = with lib.types; nullOr str; default = null; description = '' A passphrase for an SSH private key (as a Systemd credential name), usually provided on generation of the key with `rad auth`. If set to the default value of `null`, radicle will optionally import the passphrase from a credential named `${credentials.privateKeyPassphrase}`. If the passphrase is not set, radicle will prompt for it. If configured as a credential name it will be imported via `ImportCredential=` in the service configuration. Refer to the systemd-creds documentation for more details <https://systemd.io/CREDENTIALS/> ''; }; publicKey = lib.mkOption { Loading Loading @@ -304,23 +328,28 @@ in # Give only access to the private key to radicle-node. { serviceConfig = let keyCred = builtins.split ":" "${cfg.privateKeyFile}"; in if lib.length keyCred > 1 then if cfg.privateKey == null then { LoadCredentialEncrypted = [ cfg.privateKeyFile ]; # Note that neither %d nor ${CREDENTIALS_DIRECTORY} works in BindReadOnlyPaths= BindReadOnlyPaths = [ "/run/credentials/radicle-node.service/${lib.head keyCred}:${env.RAD_HOME}/keys/radicle" ]; ImportCredential = [ credentials.privateKey ]; } else if lib.types.path.check cfg.privateKey then { LoadCredential = [ "${credentials.privateKey}:${cfg.privateKey}" ]; } else { LoadCredential = [ "radicle:${cfg.privateKeyFile}" ]; BindReadOnlyPaths = [ "/run/credentials/radicle-node.service/radicle:${env.RAD_HOME}/keys/radicle" ]; ImportCredential = [ "${cfg.privateKey}:${credentials.privateKey}" ]; }; } { serviceConfig = if cfg.privateKeyPassphrase == null then { ImportCredential = [ credentials.privateKeyPassphrase ]; } else { ImportCredential = [ "${cfg.privateKeyPassphrase}:${credentials.privateKeyPassphrase}" ]; }; } ]; Loading
nixos/tests/radicle-ci-broker.nix +4 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ in meta.maintainers = with lib.maintainers; [ defelo ]; nodes.seed = { virtualisation.credentials = { "xyz.radicle.node.secret".source = "${seed-ssh-keys.snakeOilEd25519PrivateKey}"; }; services.radicle = { enable = true; privateKeyFile = seed-ssh-keys.snakeOilEd25519PrivateKey; publicKey = seed-ssh-keys.snakeOilEd25519PublicKey; node.openFirewall = true; settings = { Loading
nixos/tests/radicle.nix +4 −1 Original line number Diff line number Diff line Loading @@ -76,9 +76,12 @@ in { imports = [ commonHostConfig ]; virtualisation.credentials = { "xyz.radicle.node.secret".source = "${seed-ssh-keys.snakeOilEd25519PrivateKey}"; }; services.radicle = { enable = true; privateKeyFile = seed-ssh-keys.snakeOilEd25519PrivateKey; publicKey = seed-ssh-keys.snakeOilEd25519PublicKey; node = { openFirewall = true; Loading