kanade_shared/secrets.rs
1//! Registry-backed secret store for production credentials.
2//!
3//! Windows services run as LocalSystem and inherit Machine-scope env
4//! vars, but those vars are readable by any logged-in user. Storing
5//! the credential under HKLM with a hardened ACL (SYSTEM +
6//! Administrators only) keeps it out of low-privilege reach.
7//!
8//! Layout in use across kanade:
9//!
10//! ```text
11//! HKLM\SOFTWARE\kanade\
12//! agent\
13//! NatsToken — shared NATS bearer token (agent + backend + CLI)
14//! backend\
15//! StaticToken — KANADE_AUTH_STATIC_TOKEN counterpart
16//! JwtSecret — KANADE_JWT_SECRET counterpart
17//! MailPassword — KANADE_MAIL_PASSWORD counterpart (SMTP AUTH)
18//! ```
19//!
20//! `deploy-agent.ps1` / `deploy-backend.ps1` provision these keys and
21//! apply the ACL. Non-Windows builds get an empty stub so the
22//! workspace still cross-compiles for the CLI's Linux / macOS release
23//! artifacts.
24
25/// Read a `REG_SZ` value from `HKLM\<subkey>` and return it when
26/// non-empty. Returns `None` for missing keys, missing values, empty
27/// strings, or non-Windows targets.
28#[cfg(windows)]
29pub fn read_hklm_value(subkey: &str, value: &str) -> Option<String> {
30 use winreg::RegKey;
31 use winreg::enums::HKEY_LOCAL_MACHINE;
32
33 let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
34 let key = hklm.open_subkey(subkey).ok()?;
35 let s: String = key.get_value(value).ok()?;
36 if s.is_empty() { None } else { Some(s) }
37}
38
39#[cfg(not(windows))]
40pub fn read_hklm_value(_subkey: &str, _value: &str) -> Option<String> {
41 None
42}