astrid-runtime/astrid · critical
OS CSPRNG unavailable while generating invite suffix
Error message
OS CSPRNG unavailable while generating invite suffix
What it means
Panic from `SysRng.try_fill_bytes(&mut bytes).expect("OS CSPRNG unavailable while generating invite suffix")` in `random_suffix` (crates/astrid-kernel/src/kernel_router/admin/invite_handlers.rs:481). It draws 4 random bytes for a hex invite suffix from the OS CSPRNG and deliberately panics if that source is unavailable, refusing insecure fallback.
Solutions
- Fix the environment: allow getrandom(2) in the sandbox profile or mount /dev/urandom in the container.
- Start an entropy maintenance service (rngd, haveged) if running on hardware/VMs with slow entropy init.
- Have random_suffix return Result and map failure to an admin error response instead of panicking the handler thread.
- Check kernel logs (dmesg) for crng init failures to confirm the diagnosis.
Example fix
// before
SysRng.try_fill_bytes(&mut bytes).expect("OS CSPRNG unavailable while generating invite suffix");
// after
let suffix = SysRng.try_fill_bytes(&mut bytes)
.ok()
.map(|_| hex::encode(bytes))
.ok_or_else(|| AdminError::RngUnavailable)?; Defensive patterns
Strategy: try-catch
Validate before calling
use rand::{TryRng, rngs::SysRng};
fn rng_available() -> bool {
let mut b = [0u8; 1];
SysRng.try_fill_bytes(&mut b).is_ok()
} Try / catch
let suffix = std::panic::catch_unwind(random_suffix)
.map_err(|_| AdminError::RngUnavailable)?; // return err_bad_input-style error instead of panicking Prevention
- Check sandbox/seccomp profiles allow getrandom(2) before deploying invite handlers.
- Probe the CSPRNG once at admin-router startup.
- Convert random_suffix to return Result so handler threads degrade gracefully.
- Monitor dmesg/journald for entropy-init failures in production.
When it happens
Trigger: Any admin invite-handler request that calls `random_suffix()` while the OS entropy source fails: seccomp-filtered getrandom, missing /dev/urandom, sandboxed processes, or pre-entropy-early-boot environments.
Common situations: Same environmental causes as token generation — hardened containers, restricted service sandboxes (systemd RestrictNamespaces/seccomp profiles), minimal VM images without entropy daemons.
Related errors
- OS CSPRNG unavailable while generating invite token
- OS CSPRNG unavailable while generating default keypair name
- OS CSPRNG unavailable while generating gateway signing key
- alice
- astrid distro apply requires a signed Distro…
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/6a5c0e2fcacdbf1a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/kernel_router/admin/invite_handlers.rs:481
out.push(ch.to_ascii_lowercase());
last_was_dash = false;
} else if !last_was_dash && !out.is_empty() {
out.push('-');
last_was_dash = true;
}
}
while out.ends_with('-') {
out.pop();
}
out
}
fn random_suffix() -> String {
use rand::{TryRng, rngs::SysRng};
let mut bytes = [0u8; 4];
SysRng
.try_fill_bytes(&mut bytes)
.expect("OS CSPRNG unavailable while generating invite suffix");
hex::encode(bytes)
}
fn err_bad_input(msg: String) -> AdminResponseBody {
warn!(error = %msg, "invite request rejected: bad input");
AdminResponseBody::Error(msg)
}
fn err_internal(msg: String) -> AdminResponseBody {
warn!(error = %msg, "invite request failed: internal error");
AdminResponseBody::Error(msg)
}
fn err_unauthorized(msg: String) -> AdminResponseBody {
warn!(security_event = true, error = %msg, "invite request denied");
AdminResponseBody::Error(msg)
}
View on GitHub (pinned to affd8760f4)