Skip to content

Developer API and knowledge graph missing is_locked checks — locked data bypass #6146

@beastoin

Description

@beastoin

Summary

PR #6092 (closing #6089) fixed 15 locked data bypass paths across the main API, but the Developer API (routers/developer.py) and Knowledge Graph (routers/knowledge_graph.py) were not covered. All 6 write endpoints in the Developer API allow modifying or deleting locked conversations, memories, and action items. The PATCH endpoints also leak locked content in their responses.

This was discovered during a re-audit requested by @beastoin, who flagged the PATCH conversation endpoint in the Developer API.

Current Behavior

Developer API — Write endpoints bypass is_locked (6 endpoints)

# Method Path Line Severity Impact
D1 PATCH /v1/dev/user/conversations/{id} 1036 HIGH Can modify title/discarded + response leaks full locked conversation
D2 DELETE /v1/dev/user/conversations/{id} 1016 MEDIUM Can delete locked conversations
D3 PATCH /v1/dev/user/memories/{id} 314 HIGH Can modify content/visibility/tags/category + response leaks full locked memory
D4 DELETE /v1/dev/user/memories/{id} 296 MEDIUM Can delete locked memories
D5 PATCH /v1/dev/user/action-items/{id} 542 HIGH Can modify description/completed/due_at + response leaks full locked action item
D6 DELETE /v1/dev/user/action-items/{id} 527 MEDIUM Can delete locked action items

Note: The Developer API's READ endpoints are already protected:

  • GET conversations list: filters locked (line 763) ✓
  • GET conversation by ID: returns 404 for locked (line 870) ✓
  • GET action items: filters locked (line 430) ✓
  • GET memories: truncates locked content (line 172) ✓

Knowledge Graph — Locked memories processed into graph (1 endpoint)

# Method Path Line Severity Impact
K1 POST /v1/knowledge-graph/rebuild 52 HIGH get_memories(uid, limit=500) includes locked memories, processes full content through LLM, stores derived knowledge accessible via GET /v1/knowledge-graph

Expected Behavior

  • PATCH endpoints on locked items should return HTTP 402 (matching _get_valid_conversation_by_id() pattern from routers/conversations.py:50-58)
  • DELETE endpoints on locked items should return HTTP 402 (prevent modification of locked data)
  • Knowledge graph rebuild should filter out locked memories before LLM processing

Root Cause

PR #6092 covered 20 files but missed routers/developer.py and routers/knowledge_graph.py entirely. The Developer API was built as a separate surface from the main API and wasn't included in the original bypass audit (#6089).

Recommended Fix

Developer API (3 HIGH + 3 MEDIUM)

Add is_locked guard to all 6 write endpoints. Pattern:

# For conversations:
conversation = conversations_db.get_conversation(uid, conversation_id)
if not conversation:
    raise HTTPException(status_code=404, detail="Conversation not found")
if conversation.get('is_locked', False):
    raise HTTPException(status_code=402, detail="A paid plan is required to access this conversation.")

# For memories:
memory = memories_db.get_memory(uid, memory_id)
if not memory:
    raise HTTPException(status_code=404, detail="Memory not found")
if memory.get('is_locked', False):
    raise HTTPException(status_code=402, detail="A paid plan is required to access this memory.")

# For action items:
action_item = action_items_db.get_action_item(uid, action_item_id)
if not action_item:
    raise HTTPException(status_code=404, detail="Action item not found")
if action_item.get('is_locked', False):
    raise HTTPException(status_code=402, detail="A paid plan is required to access this action item.")

Knowledge Graph

Filter locked memories before processing:

def _rebuild_graph_task(uid: str, user_name: str):
    memories = memories_db.get_memories(uid, limit=500)
    memories = [m for m in memories if not m.get('is_locked', False)]
    rebuild_knowledge_graph(uid, memories, user_name)

Files to Modify

  • backend/routers/developer.py — 6 endpoints (D1-D6)
  • backend/routers/knowledge_graph.py — 1 endpoint (K1)

Testing

  • Unit tests for each endpoint with is_locked=True data → expect 402
  • Unit test for knowledge graph rebuild with locked memories → expect filtered out
  • Verify existing Developer API read endpoints remain protected

Related

by AI for @beastoin

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions