Skip to content

Implement multi-user support. #84

@Art9681

Description

@Art9681

Currently, Manifold only implement a single admin user. The database also only supports a single user. The current auth/session implementation is a starting point to build from. Below is a proposal.

Frontend Design

We want to implement multi-user support. This means we need to create a new view that admin users in the admin group can see from the user dropdown menu at the very right of the header. There should be a new option for "admin panel".

This admin panel should be a modal that fades in. Inside the modal there will be a left pane with the "sections". Add two sections:

  • Users
  • Config

In the right pane, the main view in the admin modal, it will render a view when we click on the sections. The Users view should display button at the top to add a new user and below that a list of current existing users. There should be a button to delete the user and another to change the password for each user row. If the new user button is clicked, then the list of users should change to a form to create a new user. For now, here is the details we want to collect for each user:

  • Username
  • Email
  • Group (User or Admin), Only admins can see the admin menu.
  • Password. The password can never be seen by admins or any other user. But the password can be changed by admins.

The modal should have a button to close the admin panel.

Ensure all necessary code is implemented in the backend to support the multi-user goal. Below is an additional proposal to aid in this implementation.

Multi-User Support Design

This document outlines a proposal for supporting multiple users on a single Manifold instance. The goal is to isolate user data so that workflows, documents and agentic memory are stored separately for each user while still using a shared PostgreSQL database with pgvector.

Motivation

Currently Manifold stores information such as ingested documents, vector embeddings and agentic memory in shared tables. When several users share an instance, data can be mixed together which is undesirable from a privacy and security standpoint. We need a strategy that keeps user data separate while reusing the same database infrastructure.

High Level Approach

  1. Tenant Mode Configuration
    Add a boolean in config.yaml (e.g. tenant_mode: true). When enabled, every new user gets a dedicated schema in Postgres.
  2. Per-User Schemas
    Upon registration a schema named tenant_<user_id> is created. All tables required by Manifold are created inside this schema: documents, inverted_index, document_metadata, agentic_memories, tool_memory, and any others that rely on pgvector.
  3. Search Path Switching
    After a user logs in, the API sets the connection’s search_path to that user’s schema. This can be done per request when acquiring a connection from the pool.
  4. Table Creation Helpers
    Existing Ensure*Table functions are updated to accept a schema name so tables are created inside the proper schema. When a new schema is created these helpers are called to initialise the tables.
  5. Backward Compatibility
    If tenant_mode is disabled Manifold behaves exactly as before using the public schema.

Implementation Steps

  1. Configuration
    • Extend DatabaseConfig with tenant_mode (boolean).
    • Optionally allow a schema_prefix to customise naming.
  2. User Registration Flow
    • After creating the user record, create the schema: CREATE SCHEMA IF NOT EXISTS tenant_<user_id>.
    • Call the table setup helpers within that schema.
  3. Connection Handling
    • Modify initUserDB, SEFII handlers and agentic memory engine to set SET search_path TO tenant_<user_id> on each acquired connection when tenant mode is enabled.
    • This ensures all queries operate on the user’s tables transparently.
  4. Table Setup
    • Update EnsureTable, EnsureInvertedIndexTable, EnsureAgenticMemoryTable, etc., to accept a schema argument and prefix all table names accordingly (e.g. fmt.Sprintf("%s.documents", schema)).
  5. User Deletion
    • When deleting a user, drop the corresponding schema to remove all related data.

Considerations

  • Security: Each user’s data lives in its own schema which prevents accidental cross-user reads. Additional row‑level permissions can be set if needed.
  • Migrations: Table structure changes must be applied to every tenant schema. A simple migration helper can iterate over schemas and run the same SQL.
  • Resource Use: Vector indexes require space. Administrators should monitor database size when many users are present.

Summary

By using one schema per user and switching the search path after authentication, Manifold can support multiple users with isolated pgvector tables while keeping a single PostgreSQL instance. Existing code can be adapted with minimal changes by parameterising table creation and ensuring the connection acquires the correct search path for each request.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions