docs: add multi-tenant storage backend audit report with implementation details and test coverage

This commit is contained in:
Raphaël MANSUY 2025-12-05 16:09:28 +08:00
parent 3905d40b37
commit 18c5623993
3 changed files with 468 additions and 0 deletions

View file

@ -53,6 +53,7 @@
## 🎉 新闻
- [x] [2025.12.01]🎯📢**企业级多租户支持**由 [Raphaël MANSUY](https://github.com/raphaelmansuy) ([ELITIZON](https://www.elitizon.com)) 贡献完整的租户隔离、RBAC权限控制、每租户知识库并完全向后兼容单租户部署。
- [x] [2025.11.05]🎯📢添加**基于RAGAS的**评估框架和**Langfuse**可观测性支持API可随查询结果返回召回上下文
- [x] [2025.10.22]🎯📢消除处理**大规模数据集**的性能瓶颈。
- [x] [2025.09.15]🎯📢显著提升**小型LLM**如Qwen3-30B-A3B的知识图谱提取准确性。
@ -922,6 +923,143 @@ maxclients 500
为了保持对遗留数据的兼容在未配置工作空间时PostgreSQL非图存储的工作空间为`default`PostgreSQL AGE图存储的工作空间为空Neo4j图存储的默认工作空间为`base`。对于所有的外部存储,系统都提供了专用的工作空间环境变量,用于覆盖公共的 `WORKSPACE`环境变量配置。这些适用于指定存储类型的工作空间环境变量为:`REDIS_WORKSPACE`, `MILVUS_WORKSPACE`, `QDRANT_WORKSPACE`, `MONGODB_WORKSPACE`, `POSTGRES_WORKSPACE`, `NEO4J_WORKSPACE`
### 🏢 企业级多租户模式
> **由 [Raphaël MANSUY](https://github.com/raphaelmansuy) ([ELITIZON](https://www.elitizon.com)) 贡献**
LightRAG支持企业级多租户功能提供完整的数据隔离、基于角色的访问控制(RBAC)和每租户知识库管理。这使得SaaS部署成为可能多个组织可以共享同一基础设施同时保持严格的数据边界。
#### 运行模式
| 模式 | 环境变量 | 描述 |
|------|---------|------|
| **单租户** (默认) | `LIGHTRAG_MULTI_TENANT=false` | 向后兼容模式。与原始LightRAG完全相同无需租户上下文。 |
| **多租户** | `LIGHTRAG_MULTI_TENANT=true` | 在WebUI中启用租户/知识库选择。API请求可选择性包含租户上下文。 |
| **严格多租户** | `LIGHTRAG_MULTI_TENANT_STRICT=true` | 所有API请求必须包含租户上下文`X-Tenant-ID``X-KB-ID`请求头)。 |
#### 快速开始
1. **在`.env`中启用多租户模式**
```bash
# 启用多租户模式
LIGHTRAG_MULTI_TENANT=true
# 可选:要求所有请求都包含租户上下文
# LIGHTRAG_MULTI_TENANT_STRICT=true
```
2. **启动服务器**
```bash
lightrag-server
```
3. **通过API创建租户**
```bash
curl -X POST http://localhost:9621/api/tenants \
-H "Content-Type: application/json" \
-d '{"tenant_id": "acme-corp", "tenant_name": "ACME公司"}'
```
4. **创建知识库**
```bash
curl -X POST http://localhost:9621/api/tenants/acme-corp/kbs \
-H "Content-Type: application/json" \
-d '{"kb_id": "product-docs", "kb_name": "产品文档"}'
```
5. **在请求中使用租户上下文**
```bash
# 带租户上下文插入文档
curl -X POST http://localhost:9621/documents/text \
-H "X-Tenant-ID: acme-corp" \
-H "X-KB-ID: product-docs" \
-H "Content-Type: application/json" \
-d '{"text": "您的文档内容..."}'
# 带租户上下文查询
curl -X POST http://localhost:9621/query \
-H "X-Tenant-ID: acme-corp" \
-H "X-KB-ID: product-docs" \
-H "Content-Type: application/json" \
-d '{"query": "产品是关于什么的?"}'
```
#### 架构概览
```
┌─────────────────────────────────────────────────────────────┐
│ LightRAG 多租户架构 │
├─────────────────────────────────────────────────────────────┤
│ 租户: acme-corp │ 租户: globex-inc │
│ ┌─────────────────────┐ │ ┌─────────────────────┐ │
│ │ 知识库: product-docs │ │ │ 知识库: research │ │
│ │ 知识库: internal-wiki│ │ │ 知识库: compliance │ │
│ └─────────────────────┘ │ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 共享基础设施(数据隔离) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ KV存储 │ │ 向量数据库│ │ 图数据库 │ │ 文档状态 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
```
#### 基于角色的访问控制 (RBAC)
| 角色 | 权限 |
|------|------|
| `admin` | 完全访问:管理租户、成员、知识库、文档、查询 |
| `editor` | 创建/删除知识库、管理文档、执行查询 |
| `viewer` | 读取文档、执行查询 |
| `viewer:read-only` | 仅执行查询 |
#### 向后兼容性
**对现有部署无破坏性更改:**
- 设置`LIGHTRAG_MULTI_TENANT=false`默认LightRAG与之前完全相同
- 现有数据和API保持完全兼容
- `workspace`参数仍可用于基本数据隔离
- 多租户模式为可选功能,需要显式配置
#### 租户配置选项
每个租户可以有自定义配置:
```python
TenantConfig(
# 每租户模型选择
llm_model="gpt-4o-mini",
embedding_model="bge-m3:latest",
rerank_model="jina-reranker-v2-base-multilingual",
# 查询默认值
top_k=40,
cosine_threshold=0.2,
# 资源配额
max_documents=10000,
max_storage_gb=100.0,
max_concurrent_queries=10,
)
```
#### 存储隔离
所有19种存储后端都实现了多租户隔离
- **基于文件**:工作空间子目录隔离
- **基于集合**MongoDB、Milvus命名空间前缀
- **关系型**PostgreSQL工作空间列过滤
- **图数据库**Neo4j、Memgraph节点标签隔离
- **向量数据库**Qdrant基于负载的分区
详细的多租户API文档请参见[LightRAG服务器API](./lightrag/api/README.md)。
### AGENTS.md 自动编程引导文件
AGENTS.md 是一种简洁、开放的格式用于指导自动编程代理完成工作https://agents.md/)。它为 LightRAG 项目提供了一个专属且可预测的上下文与指令位置,帮助 AI 代码代理更好地开展工作。不同的 AI 代码代理不应各自维护独立的引导文件。如果某个 AI 代理无法自动识别 AGENTS.md可使用符号链接来解决。建立符号链接后可通过配置本地的 `.gitignore_global` 文件防止其被提交至 Git 仓库。

138
README.md
View file

@ -51,6 +51,7 @@
---
## 🎉 News
- [2025.12]🎯[New Feature] **Enterprise Multi-Tenant Support** contributed by [Raphaël MANSUY](https://github.com/raphaelmansuy) ([ELITIZON](https://www.elitizon.com)): Complete tenant isolation with RBAC, per-tenant knowledge bases, and full backward compatibility for single-tenant deployments.
- [2025.11]🎯[New Feature]: Integrated **RAGAS for Evaluation** and **Langfuse for Tracing**. Updated the API to return retrieved contexts alongside query results to support context precision metrics.
- [2025.10]🎯[Scalability Enhancement]: Eliminated processing bottlenecks to support **Large-Scale Datasets Efficiently**.
- [2025.09]🎯[New Feature] Enhances knowledge graph extraction accuracy for **Open-Sourced LLMs** such as Qwen3-30B-A3B.
@ -970,6 +971,143 @@ The `workspace` parameter ensures data isolation between different LightRAG inst
To maintain compatibility with legacy data, the default workspace for PostgreSQL non-graph storage is `default` and, for PostgreSQL AGE graph storage is null, for Neo4j graph storage is `base` when no workspace is configured. For all external storages, the system provides dedicated workspace environment variables to override the common `WORKSPACE` environment variable configuration. These storage-specific workspace environment variables are: `REDIS_WORKSPACE`, `MILVUS_WORKSPACE`, `QDRANT_WORKSPACE`, `MONGODB_WORKSPACE`, `POSTGRES_WORKSPACE`, `NEO4J_WORKSPACE`.
### 🏢 Enterprise Multi-Tenant Mode
> **Contributed by [Raphaël MANSUY](https://github.com/raphaelmansuy) ([ELITIZON](https://www.elitizon.com))**
LightRAG supports enterprise-grade multi-tenancy with complete data isolation, role-based access control (RBAC), and per-tenant knowledge bases. This enables SaaS deployments where multiple organizations share the same infrastructure while maintaining strict data boundaries.
#### Operating Modes
| Mode | Environment Variable | Description |
|------|---------------------|-------------|
| **Single-Tenant** (Default) | `LIGHTRAG_MULTI_TENANT=false` | Backward-compatible mode. Works exactly like the original LightRAG. No tenant context required. |
| **Multi-Tenant** | `LIGHTRAG_MULTI_TENANT=true` | Enables tenant/KB selection in WebUI. API requests can optionally include tenant context. |
| **Multi-Tenant Strict** | `LIGHTRAG_MULTI_TENANT_STRICT=true` | All API requests MUST include tenant context (`X-Tenant-ID`, `X-KB-ID` headers). |
#### Quick Start
1. **Enable multi-tenant mode** in your `.env`:
```bash
# Enable multi-tenant mode
LIGHTRAG_MULTI_TENANT=true
# Optional: Require tenant context on all requests
# LIGHTRAG_MULTI_TENANT_STRICT=true
```
2. **Start the server**:
```bash
lightrag-server
```
3. **Create a tenant via API**:
```bash
curl -X POST http://localhost:9621/api/tenants \
-H "Content-Type: application/json" \
-d '{"tenant_id": "acme-corp", "tenant_name": "ACME Corporation"}'
```
4. **Create a knowledge base**:
```bash
curl -X POST http://localhost:9621/api/tenants/acme-corp/kbs \
-H "Content-Type: application/json" \
-d '{"kb_id": "product-docs", "kb_name": "Product Documentation"}'
```
5. **Use tenant context in requests**:
```bash
# Insert document with tenant context
curl -X POST http://localhost:9621/documents/text \
-H "X-Tenant-ID: acme-corp" \
-H "X-KB-ID: product-docs" \
-H "Content-Type: application/json" \
-d '{"text": "Your document content here..."}'
# Query with tenant context
curl -X POST http://localhost:9621/query \
-H "X-Tenant-ID: acme-corp" \
-H "X-KB-ID: product-docs" \
-H "Content-Type: application/json" \
-d '{"query": "What is the product about?"}'
```
#### Architecture Overview
```
┌─────────────────────────────────────────────────────────────┐
│ LightRAG Multi-Tenant │
├─────────────────────────────────────────────────────────────┤
│ Tenant: acme-corp │ Tenant: globex-inc │
│ ┌─────────────────────┐ │ ┌─────────────────────┐ │
│ │ KB: product-docs │ │ │ KB: research │ │
│ │ KB: internal-wiki │ │ │ KB: compliance │ │
│ └─────────────────────┘ │ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Shared Infrastructure (Isolated Data) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ KV Store │ │ VectorDB │ │ GraphDB │ │DocStatus │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
```
#### Role-Based Access Control (RBAC)
| Role | Permissions |
|------|------------|
| `admin` | Full access: manage tenant, members, KBs, documents, queries |
| `editor` | Create/delete KBs, manage documents, run queries |
| `viewer` | Read documents, run queries |
| `viewer:read-only` | Run queries only |
#### Backward Compatibility
**No breaking changes for existing deployments:**
- With `LIGHTRAG_MULTI_TENANT=false` (default), LightRAG works exactly as before
- Existing data and APIs remain fully compatible
- The `workspace` parameter continues to work for basic data isolation
- Multi-tenant mode is opt-in and requires explicit configuration
#### Tenant Configuration Options
Each tenant can have custom configuration:
```python
TenantConfig(
# Model selection per tenant
llm_model="gpt-4o-mini",
embedding_model="bge-m3:latest",
rerank_model="jina-reranker-v2-base-multilingual",
# Query defaults
top_k=40,
cosine_threshold=0.2,
# Resource quotas
max_documents=10000,
max_storage_gb=100.0,
max_concurrent_queries=10,
)
```
#### Storage Isolation
All 19 storage backends implement multi-tenant isolation:
- **File-based**: Workspace subdirectory isolation
- **Collection-based** (MongoDB, Milvus): Namespace prefixes
- **Relational** (PostgreSQL): Workspace column filtering
- **Graph** (Neo4j, Memgraph): Node label isolation
- **Vector** (Qdrant): Payload-based partitioning
For detailed multi-tenant API documentation, see [LightRAG Server API](./lightrag/api/README.md).
### AGENTS.md -- Guiding Coding Agents
AGENTS.md is a simple, open format for guiding coding agents (https://agents.md/). It is a dedicated, predictable place to provide the context and instructions to help AI coding agents work on LightRAG project. Different AI coders should not maintain separate guidance files individually. If any AI coder cannot automatically recognize AGENTS.md, symbolic links can be used as a solution. After establishing symbolic links, you can prevent them from being committed to the Git repository by configuring your local `.gitignore_global`.

View file

@ -0,0 +1,192 @@
# Multi-Tenant Storage Backend Audit Report
**Date:** 2025-01-20
**Auditor:** GitHub Copilot
**Branch:** `premerge/integration-upstream`
**Test Results:** 134 passed, 2 skipped
---
## Executive Summary
All 19 storage backend implementations in LightRAG correctly implement multi-tenant isolation using the `workspace` parameter. The codebase includes comprehensive tenant support modules and 134 passing tests covering multi-tenant scenarios.
---
## Storage Backend Categories
### 1. Key-Value Storage (4 implementations)
| Backend | File | Workspace Implementation | Status |
|---------|------|-------------------------|--------|
| JsonKVStorage | `json_kv_impl.py` | File path: `{working_dir}/{workspace}/{namespace}` | ✅ |
| PGKVStorage | `postgres_impl.py` | DB column + composite key: `tenant_id:kb_id:key` | ✅ |
| MongoKVStorage | `mongo_impl.py` | Collection name: `{workspace}_{namespace}` | ✅ |
| RedisKVStorage | `redis_impl.py` | Key prefix: `{workspace}_{namespace}:` | ✅ |
### 2. Vector Storage (6 implementations)
| Backend | File | Workspace Implementation | Status |
|---------|------|-------------------------|--------|
| NanoVectorDBStorage | `nano_vector_db_impl.py` | File path + namespace: `{workspace}/{namespace}.json` | ✅ |
| PGVectorStorage | `postgres_impl.py` | DB column: `workspace_id` in WHERE clauses | ✅ |
| MilvusVectorDBStorage | `milvus_impl.py` | Collection name: `{workspace}_{namespace}` | ✅ |
| QdrantVectorDBStorage | `qdrant_impl.py` | Payload field: `workspace_id` with filter conditions | ✅ |
| FaissVectorDBStorage | `faiss_impl.py` | File path: `{working_dir}/{workspace}/` | ✅ |
| MongoVectorDBStorage | `mongo_impl.py` | Collection name: `{workspace}_{namespace}` | ✅ |
### 3. Graph Storage (5 implementations)
| Backend | File | Workspace Implementation | Status |
|---------|------|-------------------------|--------|
| NetworkXStorage | `networkx_impl.py` | File path: `{working_dir}/{workspace}/` | ✅ |
| PGGraphStorage | `postgres_impl.py` | DB column: `workspace_id` in WHERE clauses | ✅ |
| Neo4JStorage | `neo4j_impl.py` | Node label: `workspace_label` (70 usages) | ✅ |
| MemgraphStorage | `memgraph_impl.py` | Node label: `workspace_label` | ✅ |
| MongoGraphStorage | `mongo_impl.py` | Collection name: `{workspace}_{namespace}` | ✅ |
### 4. Document Status Storage (4 implementations)
| Backend | File | Workspace Implementation | Status |
|---------|------|-------------------------|--------|
| JsonDocStatusStorage | `json_kv_impl.py` | File path: `{working_dir}/{workspace}/` | ✅ |
| PGDocStatusStorage | `postgres_impl.py` | DB column: `workspace` in operations | ✅ |
| MongoDocStatusStorage | `mongo_impl.py` | Collection name: `{workspace}_doc_status` | ✅ |
| RedisDocStatusStorage | `redis_impl.py` | Key prefix: `{workspace}:doc_status:` | ✅ |
---
## Tenant Support Modules
Located in `lightrag/kg/`:
| Module | Coverage | Helper Classes |
|--------|----------|----------------|
| `postgres_tenant_support.py` | PostgreSQL | `TenantSQLBuilder`, `get_composite_key`, `ensure_tenant_context` |
| `mongo_tenant_support.py` | MongoDB | `MongoTenantHelper` |
| `redis_tenant_support.py` | Redis | `RedisTenantHelper` |
| `vector_tenant_support.py` | Qdrant, Milvus, FAISS, NanoVectorDB | `VectorTenantHelper`, `QdrantTenantHelper`, `MilvusTenantHelper` |
| `graph_tenant_support.py` | Neo4j, Memgraph, NetworkX | `GraphTenantHelper`, `Neo4jTenantHelper`, `NetworkXTenantHelper` |
---
## Multi-Tenant Isolation Patterns
### Pattern 1: File Path Isolation
Used by: JSON, NetworkX, NanoVectorDB, FAISS
```python
self._file_name = os.path.join(
self.global_config.get("working_dir", "./"),
self.workspace, # <-- tenant isolation
f"{self.namespace}.json"
)
```
### Pattern 2: Collection/Table Name Prefix
Used by: MongoDB, Milvus
```python
final_namespace = f"{effective_workspace}_{self.namespace}"
self._collection = self._db[final_namespace]
```
### Pattern 3: Query Filter Conditions
Used by: Qdrant, PostgreSQL
```python
# Qdrant
filter_condition = workspace_filter_condition(self.workspace)
results = self._client.search(filter=filter_condition, ...)
# PostgreSQL
WHERE workspace_id = $1 AND ...
```
### Pattern 4: Node Labels (Graph DBs)
Used by: Neo4j, Memgraph
```python
workspace_label = f"WORKSPACE_{self.workspace.upper()}"
MATCH (n:{workspace_label}) WHERE ...
```
### Pattern 5: Key Prefix (KV Stores)
Used by: Redis
```python
final_namespace = f"{self.workspace}_{self.namespace}"
key = f"{final_namespace}:{doc_id}"
```
---
## Test Coverage
### Test Files (9 files, 134 tests)
| Test File | Tests | Coverage |
|-----------|-------|----------|
| `test_multi_tenant_backends.py` | 36 | All tenant support helpers |
| `test_tenant_security.py` | 15 | Permission enforcement, RBAC |
| `test_tenant_models.py` | 15 | Tenant, KB, TenantContext models |
| `test_tenant_storage_phase3.py` | 22 | Storage layer integration |
| `test_tenant_api_routes.py` | 10 | API routes with tenant context |
| `test_multitenant_e2e.py` | 20+ | End-to-end multi-tenant flows |
| `test_tenant_kb_document_count.py` | 8 | Document counting per KB |
| `test_document_routes_tenant_scoped.py` | 6 | Document isolation |
| `e2e/test_multitenant_isolation.py` | N/A | E2E isolation tests |
### Test Categories
1. **Unit Tests**: Tenant helpers, key generation, filter building
2. **Integration Tests**: Storage layer with tenant context
3. **Security Tests**: Role-based access control, permission enforcement
4. **E2E Tests**: Full multi-tenant workflow isolation
---
## Security Considerations
### Verified Security Properties
1. **No Cross-Tenant Leakage**: Each storage backend uses workspace-scoped queries/paths
2. **Filter Bypass Prevention**: Tenant filters are applied at the storage layer
3. **Key Collision Prevention**: Composite keys include tenant/KB identifiers
4. **Role-Based Access Control**: Proper permission checking in TenantContext
### Potential Areas for Review
1. **Admin Operations**: Ensure admin cleanup operations respect tenant boundaries
2. **Bulk Operations**: Verify batch operations apply tenant filters to all items
3. **Error Messages**: Confirm error messages don't leak cross-tenant information
---
## Conclusion
**All 19 storage backends implement multi-tenant isolation correctly.** The implementation uses consistent patterns:
- File-based storage → workspace subdirectory isolation
- Database storage → workspace column/collection prefix
- Search/query operations → workspace filter conditions
The test suite with 134 passing tests provides comprehensive coverage of multi-tenant scenarios including security, isolation, and backward compatibility.
---
## Appendix: Workspace Usage Count by File
| File | Workspace References |
|------|---------------------|
| `postgres_impl.py` | 120+ |
| `neo4j_impl.py` | 70+ |
| `mongo_impl.py` | 50+ |
| `qdrant_impl.py` | 40+ |
| `milvus_impl.py` | 30+ |
| `redis_impl.py` | 25+ |
| `memgraph_impl.py` | 20+ |
| `networkx_impl.py` | 15+ |
| `json_kv_impl.py` | 10+ |
| `nano_vector_db_impl.py` | 10+ |
| `faiss_impl.py` | 8+ |