Cognee Multi-Tenant Permissions System
Overview
Cognee’s permissions system provides multi-tenant isolation. This feature enables complete separation of data contexts, ensuring that each tenant, project, or customer has isolated access to their data with no leakage between contexts.
Key Features
- Complete Data Isolation: Each context gets separate graph and vector stores
- Dataset-Level Permissions: Fine-grained control over data access (read, write, delete, share)
- Multi-Tenant Architecture: Support for tenants, roles, and users with hierarchical permissions
- File-Based Database Isolation: Uses Kuzu (graph database) and LanceDB (vector database) for complete separation
Configuration
To enable the permissions system, set the following environment variable:
ENABLE_BACKEND_ACCESS_CONTROL=True
Important: When this is enabled, Cognee will:
- Ignore user-configured graph and vector database settings
- Enforce the use of Kuzu (file-based graph db) and LanceDB (file-based vector db)
- Deploy completely separate database instances per user per dataset
This approach ensures that each user and dataset combination gets completely separate database instances, preventing any possibility of data leakage between contexts.
Core Concepts
Permission Hierarchy
Tenant
├── Users (belong to tenant)
├── Roles (defined within tenant)
└── Datasets
├── Data (documents/files)
└── Permissions (read, write, delete, share)
Tenants
Multi-tenant isolation containers that:
- Group users and roles together
- Provide organizational boundaries
- Enable hierarchical permission management
Users
Individual system users who can:
- Belong to a tenant (or operate without a tenant)
- Have roles assigned within their tenant
- Own and access datasets based on permissions
- Be granted direct permissions on specific datasets
Roles
Permission groupings within tenants that:
- Can be assigned to multiple users
- Simplify permission management at scale
- Inherit tenant-level defaults
Datasets
Data containers that:
- Hold one or multiple documents/files
- Have separate graph and vector stores per user
- Support fine-grained permissions
- Maintain complete isolation between users
Database Isolation Mechanism
The system creates separate database directories for each user-dataset combination:
.cognee_system/
├── databases/
│ ├── user_1/
│ │ ├── dataset_a/
│ │ │ ├── kuzu_graph/
│ │ │ └── lancedb_vectors/
│ │ └── dataset_b/
│ │ ├── kuzu_graph/
│ │ └── lancedb_vectors/
│ └── user_2/
│ └── dataset_a/
│ ├── kuzu_graph/
│ └── lancedb_vectors/
Permissions
Four types of permissions available:
- read: View and search dataset contents
- write: Add new data to the dataset
- delete: Remove documents from the dataset
- share: Grant permissions to other users
Permission Management
Permission Assignment Rules
- Dataset Creation: When a user creates a dataset, they automatically receive all permissions (read, write, delete, share)
- Permission Sharing: Only users with ‘share’ permission can grant permissions to others
- Access Control: All operations check permissions before execution
- Inheritance: Users can inherit permissions through roles and tenant
Access Control Logic
The system enforces permissions at multiple levels:
- Search Operations: Users can only search datasets they have ‘read’ permission for
- Data Addition: Requires ‘write’ permission on the target dataset
- Data Deletion: Requires ‘delete’ permission on the specific documents
- Permission Sharing: Requires ‘share’ permission on the dataset
ACL (Access Control List) Structure
Permissions are managed through a relational database with the following key tables:
- principals: Base table for users, roles, and tenants
- permissions: Defines available permission types (read, write, delete, share)
- acls: Maps principals to data with specific permissions
- dataset: Represents a group of documents/files (has links to the Data table for this information) with associated permissions
NOTE: All endpoints are available via Swagger documentation at localhost:8000/docs
when running the Cognee backend.
Let’s take a quick look
1. First things first, run cognee backend.
- If you haven’t done yet, clone cognee and navigate to the root
git clone https://github.com/topoteretes/cognee.git cd cognee
- Creave venv and install dependencies
uv venv source .venv/bin/activate uv pip install -r pyproject.toml
- Run cognee backend
uvicorn cognee.api.client:app --host 0.0.0.0 --port 8000 --reload
2. Navigate to Swagger docs
Open http://localhost:8000/docs#/ in your browser.
Below is a complete step-by-step (13-steps) walkthrough showing how permissions affect user actions:
-
Before trying any endpoints, you need to login first. Login as the default user
-
Add a new dataset and note the dataset ID
-
“Cognify” to build a knowledge graph from the uploaded data
-
Search the freshly generated dataset – everything works for the default user
-
Register a second user in the system
-
Verify that the second user now appears in the user table and note the ID (We will need it while giving the permissions)
You can access the user table from your
cognee_db
depending on which relational database (SQLite or Postgres) you used in the.env
file. Below is the SQLite example.The path to the database is
/path-to-your-cognee/cognee/.cognee_system/databases/cognee_db
-
Log in with the second user’s credentials
-
Second user tries to run “cognify” on the dataset that we just added (and noted the ID) but fails due to missing “write” permissions
-
Second user attempts to give permission to themselves but is blocked as well because they don’t have the “share” permission.
Notice
principal_id
is the ID that is automatically created when we registered the second user. You should get it from theusers
table incognee_db
.In the request body, we’ll use the dataset ID that we saved in the first step.
-
Login as the default user again and grant the
write
permission to the second user. -
With
write
permission, the second user can run “Cognify” successfully. -
The default user also grants
read
permission to the second user. -
Now the second user can search the dataset without restrictions.
Join the Conversation!
Have questions about creating custom tasks? Join our community to discuss implementation strategies and best practices!