-
Notifications
You must be signed in to change notification settings - Fork 26
Description
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
- 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
- Tenant Mode Configuration
Add a boolean inconfig.yaml
(e.g.tenant_mode: true
). When enabled, every new user gets a dedicated schema in Postgres. - Per-User Schemas
Upon registration a schema namedtenant_<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 onpgvector
. - Search Path Switching
After a user logs in, the API sets the connection’ssearch_path
to that user’s schema. This can be done per request when acquiring a connection from the pool. - Table Creation Helpers
ExistingEnsure*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. - Backward Compatibility
Iftenant_mode
is disabled Manifold behaves exactly as before using the public schema.
Implementation Steps
- Configuration
- Extend
DatabaseConfig
withtenant_mode
(boolean). - Optionally allow a
schema_prefix
to customise naming.
- Extend
- 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.
- After creating the user record, create the schema:
- Connection Handling
- Modify
initUserDB
, SEFII handlers and agentic memory engine to setSET 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.
- Modify
- 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)
).
- Update
- 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.