Summary
VertexAiRagMemoryService stores Vertex RAG file display_name values as a dot-delimited string:
f"{session.app_name}.{session.user_id}.{session.id}"
search_memory() then accepts a retrieved context when its source_display_name starts with:
This makes the client-side scope check ambiguous when IDs contain dots. For example, a memory stored for app_name="demo" and user_id="alice.smith" has a legacy display name beginning with demo.alice.smith.. A search for app_name="demo" and user_id="alice" also checks for the prefix demo.alice., so it can accept the other user's memory.
Impact
This can expose Vertex RAG-backed memory across users in the same app when one user ID is a dot-prefix of another user ID, such as alice and alice.smith. If an agent uses preload memory, the returned memory can be inserted into the next model request for the wrong user.
This appears to be a follow-up to the existing user scoping fix from #1019: the current code is intended to filter by app_name and user_id, but the dot-delimited representation is not unambiguous.
Expected behavior
Memory lookup should compare the stored app/user scope exactly. Dots in app_name, user_id, or session_id should stay inside their own component instead of changing how the display name is parsed.
Proposed fix
The prepared PR changes new Vertex RAG uploads to use an encoded v1 display-name format for app_name, user_id, and session_id. Search parsing then compares the decoded components exactly. For old data, it keeps compatibility only for the unambiguous legacy three-part app.user.session form and ignores ambiguous legacy names.
Validation
The prepared PR adds unit coverage that:
- rejects a legacy collision such as
demo.alice.smith.session_secret when searching as demo / alice
- still accepts new encoded display names containing dotted app/user/session IDs
- keeps unambiguous legacy
demo.alice.legacy_session behavior
Local validation:
PYTHONPATH=src python -m pytest tests/unittests/memory -q
42 passed, 2 warnings
python -m isort --check-only src/google/adk/memory/vertex_ai_rag_memory_service.py tests/unittests/memory/test_vertex_ai_rag_memory_service.py
passed
python -m pyink --check --config pyproject.toml src/google/adk/memory/vertex_ai_rag_memory_service.py tests/unittests/memory/test_vertex_ai_rag_memory_service.py
passed
git diff --check -- src/google/adk/memory/vertex_ai_rag_memory_service.py tests/unittests/memory/test_vertex_ai_rag_memory_service.py
passed
Summary
VertexAiRagMemoryServicestores Vertex RAG filedisplay_namevalues as a dot-delimited string:f"{session.app_name}.{session.user_id}.{session.id}"search_memory()then accepts a retrieved context when itssource_display_namestarts with:f"{app_name}.{user_id}."This makes the client-side scope check ambiguous when IDs contain dots. For example, a memory stored for
app_name="demo"anduser_id="alice.smith"has a legacy display name beginning withdemo.alice.smith.. A search forapp_name="demo"anduser_id="alice"also checks for the prefixdemo.alice., so it can accept the other user's memory.Impact
This can expose Vertex RAG-backed memory across users in the same app when one user ID is a dot-prefix of another user ID, such as
aliceandalice.smith. If an agent uses preload memory, the returned memory can be inserted into the next model request for the wrong user.This appears to be a follow-up to the existing user scoping fix from #1019: the current code is intended to filter by
app_nameanduser_id, but the dot-delimited representation is not unambiguous.Expected behavior
Memory lookup should compare the stored app/user scope exactly. Dots in
app_name,user_id, orsession_idshould stay inside their own component instead of changing how the display name is parsed.Proposed fix
The prepared PR changes new Vertex RAG uploads to use an encoded v1 display-name format for
app_name,user_id, andsession_id. Search parsing then compares the decoded components exactly. For old data, it keeps compatibility only for the unambiguous legacy three-partapp.user.sessionform and ignores ambiguous legacy names.Validation
The prepared PR adds unit coverage that:
demo.alice.smith.session_secretwhen searching asdemo/alicedemo.alice.legacy_sessionbehaviorLocal validation: