fix: enforce per-user session isolation in session_search + hindsight platform gate#12571
Closed
Cyrene963 wants to merge 1 commit into
Closed
fix: enforce per-user session isolation in session_search + hindsight platform gate#12571Cyrene963 wants to merge 1 commit into
Cyrene963 wants to merge 1 commit into
Conversation
… platform gate PR 1: session_search multi-user isolation - Add user_id filter to search_messages() and list_sessions_rich() in hermes_state.py - Thread user_id parameter through session_search_tool.py - Pass self._user_id from run_agent.py call sites - Prevents cross-user data leakage in multi-user gateway deployments PR 2: Hindsight platform retain gate - Store self._platform in Hindsight __init__ - Skip memory retention for platforms without user isolation (weixin) - iLink API reports bot's own user_id for all messages, making isolation impossible Both fixes are backward-compatible: user_id=None preserves original behavior.
Author
Why disable WeChat Hindsight instead of full multi-user isolation?Root CauseThe iLink Bot API ( Verified fields from iLink API:
We inspected the adapter code ( sender_id = str(message.get("from_user_id") or "").strip()
# sender_id is ALWAYS the bot's own ID → bank_id is always the sameWhy not fix the adapter?Without a real user identifier from the API, there is no reliable way to distinguish between different WeChat users. The What would a real fix require?
This PR's approach
The WeChat Hindsight disable is a safety measure, not a design choice. It prevents the iLink API limitation from corrupting memory banks until the upstream API provides real user identification. |
Author
Cyrene963
pushed a commit
to Cyrene963/hermes-agent
that referenced
this pull request
May 7, 2026
- Add user_id parameter to MemoryStore and get_memory_dir() for per-user USER.md/MEMORY.md
- Pass user_id from AIAgent to MemoryStore during initialization
- Per-user memory directories: memories/{chat_id}/USER.md, memories/{chat_id}/MEMORY.md
- Adds session_search user_id filtering (from PR NousResearch#12571)
- Adds Hindsight per-platform retain gate (from PR NousResearch#12571)
Fixes cross-user data leakage where User A's profile and memory were
injected into User B's system prompt in multi-user gateway deployments.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Issue 1:
session_searchleaks data across usersIn multi-user gateway deployments,
session_searchsearches the entire SQLite session database without user filtering. User A can see User B's conversation history.Root cause:
search_messages()andlist_sessions_rich()have nouser_idparameter. Thesession_searchtool calls these without user scoping.Issue 2: Hindsight retains messages from platforms without user isolation
The iLink WeChat bot adapter reports
from_user_id = bot's own IDfor all messages. Different users are indistinguishable. Hindsight stores them all in one memory bank, causing cross-contamination.Fix
hermes_state.pyuser_id: str = Noneparameter tosearch_messages()andlist_sessions_rich()user_idis provided, addsWHERE s.user_id = ?to filter resultsuser_idis None (default), behavior is unchanged (backward compatible)tools/session_search_tool.pyuser_idparameter throughsession_search()and_list_recent_sessions()db.search_messages()anddb.list_sessions_rich()run_agent.pyuser_id=self._user_idin bothsession_searchcall sites (~line 7408, ~line 7889)plugins/memory/hindsight/__init__.pyself._platformfrom init kwargssync_turnfor platforms in_retain_disabled_platforms(default:('weixin',))Verification
Tested with 2 Telegram users + 1 WeChat user:
Backward Compatibility
user_id=None(default) → identical to beforeself._user_idis typically None, no changeself._user_id, filtering activatesDiff Stats
4 files changed, 27 insertions(+), 3 deletions(-)