- pgrep -f botserver matched the SSH command itself causing deadlock - replaced with pkill -f '/opt/gbo/bin/botserver' || true - added SSH keepalive (ServerAliveInterval=10, ServerAliveCountMax=3) - added Step 7: explicitly start botserver after deploy - fixed unquoted SSH_ARGS causing argument splitting - increased verify sleep from 10s to 15s
154 lines
No EOL
4.7 KiB
Markdown
154 lines
No EOL
4.7 KiB
Markdown
# USE KB 2.0: Group-Based Knowledge Base Access
|
|
|
|
## Overview
|
|
Modify the USE KB keyword to respect user group permissions, ensuring that THINK KB queries only return answers from knowledge base folders that belong to groups the logged-in user is a member of.
|
|
|
|
## Current Architecture
|
|
|
|
### USE KB Flow
|
|
1. User executes `USE KB "kb_name"` in BASIC script
|
|
2. `use_kb.rs:add_kb_to_session()` checks if KB exists in `kb_collections`
|
|
3. Creates default KB entry if not found
|
|
4. Adds association to `session_kb_associations` table
|
|
5. KB becomes active for the session
|
|
|
|
### THINK KB Flow
|
|
1. User executes `THINK KB "query"`
|
|
2. `think_kb.rs:think_kb_search()` gets all active KBs from `session_kb_associations`
|
|
3. For each active KB, calls `KnowledgeBaseManager.search()` on its Qdrant collection
|
|
4. Returns combined results from all active KBs
|
|
|
|
### Group System
|
|
- Groups stored in `rbac_groups` table
|
|
- User membership in `rbac_user_groups` table
|
|
- Group permissions via `rbac_group_roles` table
|
|
|
|
## Proposed Changes
|
|
|
|
### 1. Database Schema Changes
|
|
|
|
Add new table `kb_group_associations`:
|
|
|
|
```sql
|
|
CREATE TABLE kb_group_associations (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
kb_id UUID NOT NULL REFERENCES kb_collections(id) ON DELETE CASCADE,
|
|
group_id UUID NOT NULL REFERENCES rbac_groups(id) ON DELETE CASCADE,
|
|
granted_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(kb_id, group_id)
|
|
);
|
|
```
|
|
|
|
Migration file: `botserver/migrations/6.2.0-01-kb-groups/up.sql`
|
|
|
|
### 2. Backend Logic Changes
|
|
|
|
#### Modify `think_kb_search()` in `think_kb.rs`
|
|
- Add user group lookup before searching
|
|
- Filter active KBs to only those accessible by user's groups
|
|
- Allow access if KB has no group associations (public KBs) OR user is in associated groups
|
|
|
|
```rust
|
|
async fn think_kb_search(
|
|
kb_manager: Arc<KnowledgeBaseManager>,
|
|
db_pool: DbPool,
|
|
session_id: Uuid,
|
|
bot_id: Uuid,
|
|
user_id: Uuid, // Add user_id parameter
|
|
query: &str,
|
|
) -> Result<serde_json::Value, String> {
|
|
// Get user's groups
|
|
let user_groups = get_user_groups(&db_pool, user_id)?;
|
|
|
|
// Get active KBs filtered by groups
|
|
let accessible_kbs = get_accessible_kbs_for_session(&db_pool, session_id, &user_groups)?;
|
|
|
|
// Search only accessible KBs
|
|
// ... rest of search logic
|
|
}
|
|
```
|
|
|
|
#### Add `get_accessible_kbs_for_session()` function
|
|
```rust
|
|
fn get_accessible_kbs_for_session(
|
|
conn_pool: &DbPool,
|
|
session_id: Uuid,
|
|
user_groups: &[String],
|
|
) -> Result<Vec<(String, String, String)>, String> {
|
|
// Query that joins session_kb_associations with kb_group_associations
|
|
// Returns KBs where group_id IS NULL (public) OR group_id IN user_groups
|
|
}
|
|
```
|
|
|
|
#### Modify `add_kb_to_session()` in `use_kb.rs`
|
|
- Add optional group access check
|
|
- Allow USE KB if user has access to the KB's groups
|
|
|
|
### 3. API Changes
|
|
|
|
Add new endpoints in `rbac.rs` for KB-group management:
|
|
|
|
```rust
|
|
// Assign KB to group
|
|
POST /api/rbac/kbs/{kb_id}/groups/{group_id}
|
|
|
|
// Remove KB from group
|
|
DELETE /api/rbac/kbs/{kb_id}/groups/{group_id}
|
|
|
|
// Get groups for KB
|
|
GET /api/rbac/kbs/{kb_id}/groups
|
|
|
|
// Get KBs accessible by user
|
|
GET /api/rbac/users/{user_id}/accessible-kbs
|
|
```
|
|
|
|
### 4. Frontend Changes
|
|
|
|
#### Update `botui/ui/suite/admin/groups.html`
|
|
- Add "Knowledge Bases" tab to group detail panel
|
|
- Show list of KBs assigned to the group
|
|
- Allow adding/removing KB assignments
|
|
|
|
#### Update `botui/ui/suite/drive/drive.html`
|
|
- Add group visibility indicators for KB folders
|
|
- Show which groups have access to each KB
|
|
|
|
### 5. Migration Strategy
|
|
|
|
1. Create new migration for `kb_group_associations` table
|
|
2. Run migration to create table
|
|
3. Assign existing KBs to default groups (e.g., "all_users" group)
|
|
4. Update application code
|
|
5. Deploy and test
|
|
|
|
### 6. Backward Compatibility
|
|
|
|
- Existing KBs without group associations remain public
|
|
- Existing USE KB calls continue to work
|
|
- THINK KB will filter results based on new permissions
|
|
|
|
## Implementation Steps
|
|
|
|
1. ✅ Database migration for kb_group_associations
|
|
2. ✅ Modify think_kb_search to accept user_id and filter by groups
|
|
3. ✅ Update THINK KB keyword registration to pass user_id
|
|
4. ✅ Add group access check to USE KB
|
|
5. ✅ Add API endpoints for KB-group management
|
|
6. ✅ Update admin UI for group-KB assignment
|
|
7. ✅ Update drive UI to show group access
|
|
8. ✅ Add tests for group-based access control
|
|
|
|
## Security Considerations
|
|
|
|
- All KB access checks must happen at the database level
|
|
- No client-side filtering of search results
|
|
- Group membership verified on each request
|
|
- Audit logging for KB access attempts
|
|
|
|
## Testing
|
|
|
|
- Unit tests for group access functions
|
|
- Integration tests for THINK KB with group filtering
|
|
- UI tests for admin group-KB management
|
|
- End-to-end tests with different user group scenarios |