Users and sessions are first-class concepts in Rind. Internal runtimes manages login, logout, and user identity throughout the system via Facets and Scopes.
User Sessions via Facets
The built-in rind:user_session facet drives session lifecycle. It branches by TTY, and services can opt in via start-on:
[[service]]
name = "user-app"
run.exec = "/usr/bin/user-app"
space = "user"
start-on = [{ facet = "rind:user_session" }]
user-source = { facet = "rind:user_session", username-field = "username" }User Scopes
When a user session starts, the user orchestrator creates a per-user scope automatically:
Scope "makano"
attributes:
user: makano
units_dir: /home/makano/.local/share/units
lifetime_state: rind:user_session
This means every user gets their own metadata namespace. Their services live at makano:service-name@user-makano rather than in the static scope. It’s a poor man’s container: separate metadata, separate state, separate lifecycle.
UserContext
pub struct UserContext {
pub record: UserRecord,
pub groups: Vec<String>,
}
impl UserContext {
pub fn new(record: UserRecord, groups: Vec<String>) -> Self;
pub fn in_group(&self, group: &str) -> bool;
pub fn is_root(&self) -> bool;
pub fn is_privileged(&self) -> bool;
}UserSession
pub struct UserSession {
pub id: u64,
pub user: UserContext,
pub tty: String,
pub started_at: Instant,
}See also: Orchestrators, Context, Flow, Services