Enable Backend Access Control (EBAC) is the configuration flag that activates this multi-tenant mode, enforcing user authentication and complete data isolation.
Cognee Multi-tenancy Fundamentals
- Tenant/User: An individual or organization that uses the system. Each user has their own isolated data space.
- Dataset: A logical container for related documents and their processed knowledge graph. Each dataset belongs to a specific user and can have its own permissions.
- Principal: An entity that can be granted permissions (users, roles, or tenants).
-
Permissions: The actions allowed on a dataset:
read
: View and search dataset contentswrite
: Add data and run cognify operations on the datasetdelete
: Remove data or delete the entire datasetshare
: Grant permissions to other users, roles, or tenants
- Context Variables: Thread-local storage that ensures each request uses the correct database configuration for the authenticated user and dataset.
What Happens When EBAC is Enabled
WhenENABLE_BACKEND_ACCESS_CONTROL=true
(EBAC):
- Authentication becomes mandatory (even if
REQUIRE_AUTHENTICATION=false
) - Data isolation is enforced at the user + dataset level for graph and vector stores
- Database routing is automatic — Kùzu (graph) and LanceDB (vector) are configured per request via context variables
- Supported databases: SQLite/Postgres (relational), LanceDB (vector), Kùzu (graph)
- Custom providers are ignored — EBAC enforces Kùzu and LanceDB regardless of user configuration
Under the Hood: Architecture & Storage Layout
When EBAC is enabled, Cognee automatically:- Overrides database configurations — user-provided graph/vector settings are ignored and replaced with user+dataset-specific paths
- Sets context variables for each request:
graph_db_config
→ points to Kùzu database file for the specific user+dataset combinationvector_db_config
→ points to LanceDB directory for the specific user+dataset combinationfile_storage_config
→ sets file storage root to the user’s tenant directory (or user ID if no tenant)
- Enforces permission checks — all operations verify that the user has appropriate permissions on the requested dataset
- Each user gets their own database directory
- Each dataset gets its own database files within the user’s directory
- File storage is organized by tenant (if user belongs to one) or by user ID
- This structure prevents any cross-user data access at the filesystem level
Permission System
-
Permission types:
read
: View and search dataset contentswrite
: Add data and run cognify operations on the datasetdelete
: Remove data or delete the entire datasetshare
: Grant permissions to other users, roles, or tenants
-
Permission resolution order:
- Direct user permissions — explicitly granted to the user
- Role permissions — inherited through the user’s role memberships
- Tenant permissions — inherited through the user’s tenant membership
- Dataset ownership: Creating a dataset automatically grants the creator all four permissions; dataset owners can grant any permission to other principals
-
Operation requirements:
add
/cognify
operations → requirewrite
permissionsearch
operations → requireread
permissiondelete
operations → requiredelete
permission- Permission management → requires
share
permission
Current Limitations
- Supported databases: SQLite/Postgres (relational), LanceDB (vector), Kùzu (graph)
- Visualization:
GET /api/v1/visualize?dataset_id=<UUID>
requiresread
permission - Cross-dataset search: Queries are dataset-scoped; cross-dataset searches run per authorized dataset context
- Custom providers: Graph/vector database providers are locked to Kùzu/LanceDB when EBAC is enabled