- 1
//! The durable gateway bearer token. - 2
/// Ensure a durable gateway bearer token exists, and return it. - 3
/// - 4
/// Pinned at **activation**, which is the moment a token first has to - 5
/// outlive a process: a bridge unit, the tray's "Open Admin Console", and - 6
/// any saved console link all authenticate against it, and a token minted - 7
/// per boot invalidates every one of them on each restart. - 8
/// - 9
/// This used to happen in `vak self install`. It was removed when install - 10
/// stopped activating anything (doc 46 D6) and the note said it moved - 11
/// here — but it did not, so a freshly installed machine registered a - 12
/// bridge unit that could never authenticate and crash-looped with - 13
/// "gateway token missing". Found by installing the stack for real. - 14
/// - 15
/// Idempotent: an existing value is never replaced, so activating again - 16
/// does not invalidate a link already in use. An explicitly empty value is - 17
/// left alone too — that is a deliberate "unpinned" choice. - 18
pub fn ensure_gateway_token() -> Result<(), String> { - 19
const KEY: &str = "VAK_GATEWAY_TOKEN"; - 20
let Some(path) = vak_config::user_env_path() else { - 21
return Ok(()); - 22
}; - 23
if vak_config::read_env_file_var(&path, KEY).is_some() { - 24
return Ok(()); - 25
} - 26
let token = format!("vk_{}", uuid::Uuid::now_v7()); - 27
vak_config::upsert_env_file(&path, KEY, &token) - 28
.map_err(|e| format!("writing {}: {e}", path.display()))?; - 29
// Visible to this process immediately, so a server started right after - 30
// activation uses the pinned value rather than minting its own. - 31
vak_config::set_override(KEY, token); - 32
Ok(()) - 33
} - 34
- 35
#[cfg(test)] - 36
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] - 37
mod tests { - 38
use super::*; - 39
- 40
/// The defect a real install exposed: with nothing pinning a token, - 41
/// every boot minted a new one, so a bridge unit registered at - 42
/// activation could never authenticate and crash-looped. - 43
#[test] - 44
fn activation_pins_a_token_and_never_replaces_an_existing_one() { - 45
let home = vak_config::paths::isolate_home_for_tests(); - 46
let path = vak_config::user_env_path().expect("user env path"); - 47
vak_config::remove_env_file_key(&path, "VAK_GATEWAY_TOKEN").unwrap(); - 48
vak_config::clear_override("VAK_GATEWAY_TOKEN"); - 49
- 50
ensure_gateway_token().unwrap(); - 51
let first = vak_config::read_env_file_var(&path, "VAK_GATEWAY_TOKEN") - 52
.expect("a token must be pinned"); - 53
assert!(first.starts_with("vk_"), "a token must be pinned: {first}"); - 54
- 55
// Re-activating must not invalidate a link already in use. - 56
ensure_gateway_token().unwrap(); - 57
assert_eq!( - 58
vak_config::read_env_file_var(&path, "VAK_GATEWAY_TOKEN").unwrap(), - 59
first, - 60
"re-activation replaced an existing token" - 61
); - 62
assert!(home.exists()); - 63
} - 64
} - 65
Indexing the workspace…
Vakyartha documentation is discovering safe artifacts, anchors, and source references.