graphiti/.serena/memories/multi_user_security_analysis.md
Lars Varming 341efd8c3d Fix: Critical database parameter bug + index creation error handling
CRITICAL FIX - Database Parameter (graphiti_core):
- Fixed graphiti_core/driver/neo4j_driver.py execute_query method
- database_ parameter was incorrectly added to params dict instead of kwargs
- Now correctly passed as keyword argument to Neo4j driver
- Impact: All queries now execute in configured database (not default 'neo4j')
- Root cause: Violated Neo4j Python driver API contract

Technical Details:
Previous code (BROKEN):
  params.setdefault('database_', self._database)  # Wrong - in params dict
  result = await self.client.execute_query(cypher_query_, parameters_=params, **kwargs)

Fixed code (CORRECT):
  kwargs.setdefault('database_', self._database)  # Correct - in kwargs
  result = await self.client.execute_query(cypher_query_, parameters_=params, **kwargs)

FIX - Index Creation Error Handling (MCP server):
- Added graceful handling for Neo4j IF NOT EXISTS bug
- Prevents MCP server crash when indices already exist
- Logs warning instead of failing initialization
- Handles EquivalentSchemaRuleAlreadyExists error gracefully

Files Modified:
- graphiti_core/driver/neo4j_driver.py (3 lines changed)
- mcp_server/src/graphiti_mcp_server.py (12 lines added error handling)
- mcp_server/pyproject.toml (version bump to 1.0.5)

Testing:
- Python syntax validation: PASSED
- Ruff formatting: PASSED
- Ruff linting: PASSED

Closes issues with:
- Data being stored in wrong Neo4j database
- MCP server crashing on startup with EquivalentSchemaRuleAlreadyExists
- NEO4J_DATABASE environment variable being ignored

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 11:37:16 +01:00

2.8 KiB

Multi-User Security Analysis - Group ID Isolation

Analysis Date: November 9, 2025

Question: Should LLMs be able to specify group_id in multi-user LibreChat?

Answer: NO - This creates a security vulnerability

Security Issue

Current Risk:

  • Multiple users → Separate MCP instances → Shared database (Neo4j/FalkorDB)
  • If LLM can specify group_id parameter, User A can access User B's data
  • group_id is just a database filter, not a security boundary

Example Attack:

# User A's LLM could run:
search_nodes(query="passwords", group_ids=["user_b_456"])
# This would search User B's graph!

Option 3: Security Flag (RECOMMENDED)

Add configurable enforcement of session isolation:

# config.yaml
graphiti:
  group_id: ${GRAPHITI_GROUP_ID:main}
  enforce_session_isolation: ${ENFORCE_SESSION_ISOLATION:false}

For LibreChat multi-user:

env:
  GRAPHITI_GROUP_ID: "{{LIBRECHAT_USER_ID}}"
  ENFORCE_SESSION_ISOLATION: "true"  # NEW: Force isolation

Tool Implementation:

@mcp.tool()
async def search_nodes(
    query: str,
    group_ids: list[str] | None = None,
    ...
):
    if config.graphiti.enforce_session_isolation:
        # Security: Always use session group_id
        effective_group_ids = [config.graphiti.group_id]
        if group_ids and group_ids != [config.graphiti.group_id]:
            logger.warning(
                f"Security: Ignoring group_ids {group_ids}. "
                f"Using session group_id: {config.graphiti.group_id}"
            )
    else:
        # Backward compat: Allow group_id override
        effective_group_ids = group_ids or [config.graphiti.group_id]

Benefits

  1. Secure by default for LibreChat: Set flag = true
  2. Backward compatible: Single-user deployments can disable flag
  3. Explicit security: Logged warnings show attempted breaches
  4. Flexible: Supports both single-user and multi-user use cases

Implementation Scope

7 tools need security enforcement:

  1. add_memory
  2. search_nodes (+ search_memory_nodes wrapper)
  3. get_entities_by_type
  4. search_memory_facts
  5. compare_facts_over_time
  6. get_episodes
  7. clear_graph

5 tools don't need changes:

  • get_entity_edge (UUID-based, already isolated)
  • delete_entity_edge (UUID-based)
  • delete_episode (UUID-based)
  • get_status (global status, no data access)

Security Properties After Fix

Users cannot access other users' data
LLM hallucinations/errors can't breach isolation
Prompt injection attacks can't steal data
Configurable for different deployment scenarios
Logged warnings for security monitoring

  • LibreChat Setup: DOCS/Librechat.setup.md
  • Verification: .serena/memories/librechat_integration_verification.md
  • Implementation: mcp_server/src/graphiti_mcp_server.py