Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/agent0ai/space-agent/llms.txt

Use this file to discover all available pages before exploring further.

Space Agent’s multi-user model is built around a three-layer filesystem: firmware at L0 (read-only, maintained by developers), group configuration at L1 (written by group managers and admins), and personal workspaces at L2 (written only by each individual user). Every permission decision — from module resolution to file writes — flows from group membership recorded in group.yaml files under L1/<group-id>/. This means access control is always auditable on disk, and the CLI is the only tool you need to manage it.
Before creating any users or groups in production, make sure CUSTOMWARE_PATH is set: node space set CUSTOMWARE_PATH=/srv/space/customware. This ensures CLI writes land in the correct writable root rather than inside the source checkout.

User Management

Creating users

node space user create <username> \
  --password <password> \
  [--full-name "<Display Name>"] \
  [--groups <group[,group...]>]
The --groups flag accepts a comma-separated list of group IDs. Groups that do not yet exist in L1 are created automatically. For example:
# Basic user with no groups
node space user create alice --password secret123

# User with a display name and group memberships
node space user create bob \
  --password secret456 \
  --full-name "Bob Example" \
  --groups team-red,developers

# Admin user
node space user create sysadmin \
  --password "strongpass" \
  --full-name "System Admin" \
  --groups _admin
Use --force to replace an existing user directory:
node space user create alice --password newpass --force

Changing passwords

Changing a password rewrites the sealed SCRAM verifier and clears all active sessions for that user. The user will need to log in again on all devices.
node space user password alice --password newsecret456

Group Model

Groups are the central organizing primitive. A user belongs to one or more groups, and those groups determine which L0 and L1 paths they can read, and which L1 paths they can write.

Built-in groups

Group IDDescriptionWho creates itWhat members can write
_allAll users (firmware group, defined at L0)Developer-maintainedNothing — read only
_adminAdmin usersCreated automatically on first --groups _admin usageAny L1 or L2 path
Custom (e.g. team-red)Team or role groupsCLI: node space group createL1/<group-id>/... when manager
_all is a firmware-level group defined at L0. It is always present and includes every authenticated user. You cannot create, modify, or delete it through the CLI.

Creating custom groups

node space group create team-red
Use --force to reinitialize an existing group directory:
node space group create team-red --force

Adding members

# Add a user to a group
node space group add team-red user alice

# Add a sub-group (all members of qa-team also become members of team-red)
node space group add team-red group qa-team

Making a user a group manager

Group managers can write L1/<group-id>/... — they can update the group’s shared modules, skills, and configuration. Add --manager to grant manager status:
node space group add team-red user alice --manager

# A whole sub-group can also be a managing group
node space group add team-red group ops --manager

Removing members

node space group remove team-red user alice
node space group remove team-red group qa-team

# Remove manager status without removing membership
node space group remove team-red user alice --manager

Access Control Model

The permission model is enforced server-side by server/lib/customware/file_access.js on every request. There are no client-controlled overrides.

What users can read

  • Their own L2/<username>/ tree
  • Any L0/<group>/ root for groups they belong to
  • Any L1/<group>/ root for groups they belong to

What users can write

  • Only their own L2/<username>/...
  • L1/<group-id>/... if they are a manager of that group
  • Any L1 or L2 path if they are in _admin
Nobody writes L0. Firmware content is maintained by developers in the source checkout and is never writable at runtime, regardless of group membership.

The admin shell

The /admin route is clamped to maxLayer=0 — it resolves modules and extensions from L0 only, ignoring all L1 and L2 customizations. This gives administrators a stable, unmodified control plane even if a group or user customware layer breaks something in the regular app shell. Only _admin group members can access admin features through this route.

Layer override order

When the server resolves a module for a given user, it layers overrides in this order (last wins):
  1. L0/_all (firmware baseline, all users)
  2. L0/<group>/ for each group the user belongs to
  3. L1/_all (shared server customizations)
  4. L1/<group>/ for each group the user belongs to
  5. L2/<username>/ (personal workspace)

Login and Access Gating

Disabling password login

Set LOGIN_ALLOWED=false to block the password-login form and endpoints while keeping the public shell available. Existing authenticated sessions continue to work normally.
node space set LOGIN_ALLOWED=false
This is useful when you want to lock down the login surface temporarily without taking the server offline.

Single-user mode (no login required)

SINGLE_USER_APP=true makes every request resolve to an implicit user principal with _admin access. No login is required. This is used by the desktop app and is appropriate for completely personal, single-person deployments.
node space set SINGLE_USER_APP=true
Do not use SINGLE_USER_APP=true on a publicly accessible server. All visitors will have full admin access with no authentication.

Guest Users

Guest accounts allow anonymous visitors to create temporary sessions from the login screen, useful for demo servers and public instances.

Enabling guest accounts

ALLOW_GUEST_USERS defaults to false. Guest account creation requires both ALLOW_GUEST_USERS=true and LOGIN_ALLOWED=true:
node space set ALLOW_GUEST_USERS=true
node space set LOGIN_ALLOWED=true
Guest usernames are randomized (guest_...). The server’s periodic maintenance jobs automatically clean up stale guest accounts:
  • Inactive guests are deleted after 72 hours of no file activity (checked hourly).
  • Oversized guests are deleted when their folder exceeds 1,000 files or 1 GB of tracked data (checked every 5 minutes).
Both cleanup jobs are disabled automatically when ALLOW_GUEST_USERS=false.

Per-User Disk Quotas

USER_FOLDER_SIZE_LIMIT_BYTES caps the on-disk size of each user’s L2/<username>/ folder. Set to 0 (the default) to disable quotas entirely.
# 500 MB per user
node space set USER_FOLDER_SIZE_LIMIT_BYTES=524288000

# 1 GB per user
node space set USER_FOLDER_SIZE_LIMIT_BYTES=1073741824

# Disable quotas
node space set USER_FOLDER_SIZE_LIMIT_BYTES=0
When a user folder is at or above the cap, only mutations that reduce its size (deletions, smaller writes) are permitted. Quota accounting is cached per user and updated incrementally; the server does not rescan user folders on every request.

Cloud Sharing

Space Agent supports hosted cloud-share uploads, allowing users to publish and share their spaces with a link. CLOUD_SHARE_ALLOWED defaults to false.
# Enable this server to receive hosted cloud-share uploads
node space set CLOUD_SHARE_ALLOWED=true

# Override the default cloud-share receiver URL shown to users
node space set CLOUD_SHARE_URL=share.your-domain.com
CLOUD_SHARE_URL defaults to share.space-agent.ai. It is exposed to the frontend so the share modal shows users the correct upload target and generates valid share links.
CLOUD_SHARE_ALLOWED enables the receiving side on this server. It depends on guest users being available and CUSTOMWARE_PATH being configured so share archives land under CUSTOMWARE_PATH/share/spaces/.

Build docs developers (and LLMs) love