Skip to content
Xila
Demonstration

Users

The Users module is Xila's in-memory identity and group membership registry.

Last updatedEdit page

The Users module is Xila’s in-memory identity and group membership registry.

  • Supplies user/group identity data for permission checks and ownership metadata.
  • Allocates and resolves typed identifiers used by task and VFS layers.
  • Guarantees root account/group bootstrap at manager initialization.

In scope

  • User/group insertion and lookup.
  • Membership tracking (add_to_group, is_in_group, get_user_groups).
  • Identifier and name resolution APIs.

Out of scope

  • Credential verification policy (current check_credentials is placeholder-like).
  • Authentication/session/token management.
  • Persistent storage (state is runtime memory only).
  • Explicit users::Manager::new() with references passed to VFS, authentication, and executables.
  • Internal RwLock protects:
    • users: BTreeMap<UserIdentifier, InternalUser>,
    • groups: BTreeMap<GroupIdentifier, InternalGroup>.
  • InternalUser stores name + primary group.
  • InternalGroup stores group name + membership set (BTreeSet<UserIdentifier>).

Contract vs implementation

  • Contract: typed identifier APIs and membership/name lookup behavior.
  • Implementation: exact map/set layout, root bootstrap details, allocation scan strategy.
graph TD
    Clients@{ shape: processes, label: "Modules / executables" }
    Auth[authentication crate]
    UsersAPI[users module API]
    Manager[Explicit Users Manager]
    Lock[RwLock]
    UsersMap[(users map)]
    GroupsMap[(groups map)]

    Clients -->|query / permission checks| UsersAPI
    Auth -->|create/load accounts| UsersAPI
    UsersAPI --> Manager
    Manager --> Lock
    Lock --> UsersMap
    Lock --> GroupsMap
    UsersMap -->|primary_group id| GroupsMap
  1. Construct a manager; root user/group are inserted immediately.
  2. Allocate identifiers for additional users/groups.
  3. Register users/groups and membership before launching constrained workloads.
  4. Query identity/membership during runtime from task/VFS policy paths.
  • Task metadata uses user/group identifiers from this module.
  • VFS permission checks use the supplied users manager’s is_in_group(...) method.
  • Name-based resolution provides bridge between human-readable config and typed runtime ids.
  • Single RwLock guards all user/group data.
  • Read operations scale concurrently.
  • Mutating operations (add user/group/member) take write lock and enforce duplicate checks.
  • Used directly by Task and Virtual file system.
  • Higher-level authentication crate composes over this module rather than embedding inside it.
  • Duplicate identifiers/names return explicit duplicate errors.
  • Invalid user/group references return typed invalid-identifier errors.
  • Identifier allocation fails with TooManyUsers / TooManyGroups on range exhaustion.
  • Add richer metadata per user/group while preserving typed id model.
  • Add batch APIs for provisioning workflows.
  • Add persistent snapshot/load layers in higher-level components.
  • Runtime-only storage; no built-in persistence.
  • Current credential-check method is not a complete authentication implementation.
  • One manager lock coordinates its identity registry.

Persistent groups are loaded before users. Registering a restored user tolerates primary-group membership already present in the saved group; duplicate user identifiers and names still fail.

Registry invariants and implementation caveats

Section titled “Registry invariants and implementation caveats”

The manager stores users and groups in BTreeMap collections behind an asynchronous RwLock<CriticalSectionRawMutex, _>; each group’s membership is a BTreeSet<UserIdentifier>. Manager::new() creates the root user and root group. Identifier allocation helpers scan from their minimum value until an unused identifier is found and report TooManyUsers or TooManyGroups at the limit.

add_user(id, name, primary_group) rejects duplicate user IDs and names. The implementation inserts the user into the map before resolving the primary group. A missing primary group therefore returns InvalidGroupIdentifier after the user record was inserted, so callers should validate that the group exists before calling add_user. The group membership insertion is idempotent to support restoration of previously loaded membership. The initial root group is constructed with an empty membership set, so is_in_group(UserIdentifier::ROOT, GroupIdentifier::ROOT) does not automatically return true solely because the root user has that primary group.

add_group(id, name, users) rejects duplicate group IDs and names, and initializes membership from the supplied slice. add_to_group() checks group existence, then inserts a user identifier; it does not itself verify that the user exists. Membership queries read the group sets, not a separately maintained reverse index.

check_credentials() currently returns true unconditionally. Do not treat it as an authentication or authorization boundary. Credential verification and session policy must be provided by the appropriate authentication component. The registry itself is in-memory; persistence is handled by surrounding system integration rather than automatically by Manager.