How to Configure Multi-User Permissions and Role-Based Access Control in AnythingLLM

AnythingLLM implements role-based access control (RBAC) through a multi-user mode that assigns one of three hierarchical roles—admin, manager, or default—to govern workspace visibility, user management, and API access.

The Mintplex-Labs/anything-llm repository provides a comprehensive RBAC system built into its Express.js backend. By toggling a system-wide flag and applying middleware to routes, administrators can enforce granular permissions that determine who can create workspaces, manage users, or access specific API endpoints.

Understanding the RBAC Architecture

The permission system rests on three core components: a global multi-user flag, symbolic role constants, and Express middleware validators.

The Multi-User Flag

All RBAC checks depend on SystemSettings.isMultiUserMode, defined in server/models/systemSettings.js (lines 406-414). This method reads the multi_user_mode boolean from the system_settings table. When this flag is false, the application runs in single-user mode and all RBAC middleware short-circuits to allow unrestricted access.

Role Definitions

Roles are defined as constants in server/utils/middleware/multiUserProtected.js:

  • admin – Full system access, including user management and global settings.
  • manager – Moderate access; can view all workspaces but cannot modify system settings.
  • default – Regular user; can only access explicitly assigned workspaces.
  • all – A wildcard used in middleware to match any role.

These strings are stored in the role column of the users table, managed by server/models/user.js.

Middleware Enforcement

The same file exports two validation helpers:

  • strictMultiUserRoleValid(allowedRoles) – Denies the request with 401 Unauthorized if multi-user mode is disabled or if the requesting user's role is not in the allowed list.
  • flexUserRoleValid(allowedRoles) – Only enforces the role check when multi-user mode is active; permits all requests in single-user mode.

Enabling Multi-User Mode

You can activate RBAC through the web interface or programmatically via the REST API.

Via the User Interface

Navigate to System Settings and toggle "Multi-User Mode". This updates the multi_user_mode value in the database and immediately enforces role checks on protected routes.

Via the API

Send a PUT request to the system settings endpoint:

curl -X PUT https://your-instance.com/v1/system/settings \
     -H "Authorization: Bearer <API_KEY>" \
     -H "Content-Type: application/json" \
     -d '{"multi_user_mode": true}'

The endpoint invokes SystemSettings.updateSettings, persisting the flag to the system_settings table.

Managing Users and Roles

Once multi-user mode is active, administrators can create accounts and assign roles through the Admin API defined in server/endpoints/api/admin/index.js.

Creating Users

To create a new user with a specific role:

curl -X POST https://your-instance.com/v1/admin/users/new \
     -H "Authorization: Bearer <API_KEY>" \
     -H "Content-Type: application/json" \
     -d '{
           "username": "jane-manager",
           "password": "StrongPass!23",
           "role": "manager"
         }'

Valid roles are "admin", "manager", or "default". The endpoint returns the created user object including the assigned role.

Role Validation

The helper validRoleSelection in server/utils/helpers/admin/index.js ensures that only legitimate roles are written to the database. Attempting to assign an undefined role results in a validation error before the User.create method in server/models/user.js is invoked.

Workspace Access Control

Role-based filtering occurs in server/models/workspace.js (lines 70-73). The Workspace.getWithUser method implements the following logic:

if ([ROLES.admin, ROLES.manager].includes(user.role))
    return this.get(clause);          // admins & managers see all workspaces
// otherwise only workspaces the user belongs to

Consequently, admin and manager users bypass workspace membership checks, while default users only retrieve workspaces where an explicit workspace_user association exists.

Protecting Custom Routes

To enforce RBAC on your own Express routes, import the middleware from server/utils/middleware/multiUserProtected.js:

const { strictMultiUserRoleValid, ROLES } = require("./server/utils/middleware/multiUserProtected");

// Only admins may delete a workspace
app.delete(
  "/v1/workspaces/:id",
  [validApiKey, strictMultiUserRoleValid([ROLES.admin])],
  async (req, res) => {
    const { id } = req.params;
    // … workspace deletion logic …
    res.json({ success: true });
  }
);

The strictMultiUserRoleValid middleware performs three checks:

  1. Verifies SystemSettings.isMultiUserMode() returns true.
  2. Loads the requesting user via session or API key.
  3. Returns 401 Unauthorized if the user's role is not included in the allowed array.

For routes that should remain accessible in single-user mode but restrict roles when multi-user mode is active, use flexUserRoleValid instead.

Summary

  • Multi-user mode is controlled by the multi_user_mode flag in SystemSettings, stored in the database and checked on every request.
  • Three roles govern access: admin (full control), manager (read-all workspaces), and default (restricted to assigned workspaces).
  • Middleware strictMultiUserRoleValid and flexUserRoleValid enforce role checks on API routes, short-circuiting when multi-user mode is disabled.
  • User management occurs through the Admin API (/v1/admin/users/*), with role validation handled by validRoleSelection in the admin helpers.
  • Workspace visibility is automatically filtered by role in Workspace.getWithUser, ensuring managers and admins see all workspaces while default users see only their assignments.

Frequently Asked Questions

What happens if I try to access an admin endpoint when multi-user mode is disabled?

The strictMultiUserRoleValid middleware checks SystemSettings.isMultiUserMode() before evaluating roles. If the flag is false, the middleware returns 401 Unauthorized immediately, preventing access to admin-only routes regardless of any API key provided.

Can I create custom roles beyond admin, manager, and default?

The current RBAC implementation in server/utils/middleware/multiUserProtected.js defines only admin, manager, default, and the all wildcard. The validRoleSelection helper in server/utils/helpers/admin/index.js explicitly validates against this list. Adding custom roles would require modifying these files and updating the database schema constraints on the users.role column.

How does workspace access differ between managers and default users?

According to the logic in server/models/workspace.js (lines 70-73), both admin and manager roles bypass workspace membership filters and retrieve all workspaces via this.get(clause). In contrast, default users only receive workspaces where an explicit workspace_user association exists, effectively restricting them to assigned workspaces only.

Is there a way to protect routes only when multi-user mode is active, but allow them otherwise?

Yes, the flexUserRoleValid middleware in server/utils/middleware/multiUserProtected.js is designed exactly for this scenario. It only enforces role validation when SystemSettings.isMultiUserMode() returns true. In single-user mode, the middleware passes control to the next handler without checking roles, making it ideal for routes that should remain accessible in standalone deployments but restricted in multi-user environments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →