From ae39f24b5882c280c5c9608ddab43722c36ddcdb Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Fri, 3 Oct 2025 09:06:25 +0200 Subject: [PATCH] node: Support systemd credential for secret MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While it is possible to use systemd credentials via LoadCredential=xyz.radicle.node.secret:… ExecStart=radicle-node … --secret "${CREDENTIALS_DIRECTORY}/xyz.radicle.node.secret" Make usage more convenient and directly support passing the secret key via a systemd credential. The ID of the credential must be xyz.radicle.node.secret and is not user-configurable. A systemd service unit file might contain: LoadCredential=xyz.radicle.node.secret:… ExecStart=radicle-node … This requires just a bit of plumbing in `radicle-node`. The preference order for the path of the secret key is: 1. The command line argument `--secret`. 2. The systemd credential. 3. The configuration file. 4. The default location to preserve backward compatibility. The reason to prefer the systemd credential over the configuration file is that it uses a mechanism that is influenced by the environment of the process, which is deemed "closer at runtime" or "more dynamic" than a configuration file. Ad-hoc overrides are still possible via the commandline argument. --- CHANGELOG.md | 6 ++++++ crates/radicle-node/src/main.rs | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4ff9841..10039533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `rad issue` now uses `clap` to parse its command-line arguments. This affects error reporting as well as help output. +- `radicle-node` now supports systemd Credentials (refer to + for more information) to load + the secret key, in addition to the commandline argument + `--secret` (higher priority than the credential) and the + configuration file (lower priority than the credential). + The identifier of the credential is "xyz.radicle.node.secret". ## Fixed Bugs diff --git a/crates/radicle-node/src/main.rs b/crates/radicle-node/src/main.rs index 9c9c68c8..fac2fed5 100644 --- a/crates/radicle-node/src/main.rs +++ b/crates/radicle-node/src/main.rs @@ -237,8 +237,21 @@ fn execute(options: Options) -> Result<(), ExecutionError> { let passphrase = profile::env::passphrase(); - let secret_path = options - .secret + let secret_path = options.secret; + + #[cfg(all(feature = "systemd", target_os = "linux"))] + let secret_path = secret_path.or_else(|| { + const ID: &str = "xyz.radicle.node.secret"; + match radicle_systemd::credential::path(ID) { + Err(err) => { + log::warn!(target: "node", "Failed to obtain path of the secret key via systemd credential with ID '{ID}': {err}"); + None + }, + Ok(path) => path + } + }); + + let secret_path = secret_path .or_else(|| config.node.secret.clone()) .unwrap_or_else(|| home.keys().join("radicle"));