How it works
Store items are organized by a namespace tuple (for example,("memories", "preferences")) and a key. Unlike threads and assistants, store namespaces are defined by your application, so authorization works differently:
- Your
@auth.authenticatehandler validates the caller and returns a uniqueidentityfor each user. - Your
@auth.on.storehandler either validates that the namespace starts with that identity, or rewrites the namespace to prepend it. - The server uses the validated or rewritten namespace for the actual read or write.
("memories",) with automatic prefix rewriting actually stores data at ("user-123", "memories"). Another user cannot read or overwrite that data because their requests are scoped to ("user-456", ...).
Store authorization handlers receive a mutable
value dict. Changes to value["namespace"] take effect on the operation. You do not return a metadata filter like you do for threads.Prerequisites
- A LangSmith Deployment with custom authentication configured.
- An
@auth.authenticatehandler that returns a stable, uniqueidentityfor each end user.
Configure auth in LangSmith Deployment
Point your deployment at your auth module inlanggraph.json:
auth object must expose an instance of langgraph_sdk.Auth (commonly named auth).
Choose a store authorization pattern
Store isolation requires a@auth.on.store handler. Two common patterns work well; pick one based on where you want user scoping to live.
Both patterns use a single
@auth.on.store handler that covers all store actions (put, get, search, delete, and list_namespaces). You only need action-specific handlers such as @auth.on.store.put if you want different rules per operation.
Explicit namespace + deny
Your application code includes the user’s identity as the first segment of every namespace (for example,("user-123", "memories")). The auth handler validates that the caller matches that prefix and rejects mismatches:
("user-456", "memories") fails immediately if the authenticated user is user-123. The tradeoff is that every store call in your agent must include the user prefix, typically from runtime context such as config["configurable"]["langgraph_auth_user_id"].
Automatic prefix rewriting
Your application code uses logical namespaces without a user prefix (for example,("memories", "preferences")). The auth handler prepends the authenticated user’s identity on every store operation:
list_namespaces without a prefix, value["namespace"] is empty. The handler above treats an empty namespace as (ctx.user.identity,), so the user only sees their own namespaces.
This pattern keeps agent code simpler because the auth layer handles user isolation transparently. The tradeoff is that you must not also prefix namespaces in application code, or you will double-scope data and break reads. Pick one scoping layer: auth rewriting or application-level namespaces, not both.
Use namespaces in agent code
If you use automatic prefix rewriting, your graph code uses logical namespaces without the user prefix. The auth layer adds the user scope automatically at request time. Put the following in your graph nodes or tools (for example,graph.py):
("user-a", "memories", "preferences"). User B’s requests never reach that namespace.
If you use explicit namespace + deny, include the user identity in every namespace from your graph code instead:
Deep Agents and StoreBackend
If you use Deep Agents with aStoreBackend, align your namespace factory with the auth-scoped layout. When auth prepends ctx.user.identity, use logical namespaces in the backend and let auth handle user isolation:
rt.server_info.user.identity), ensure your auth handler does not double-prefix namespaces. Pick one scoping layer: auth rewriting or application-level namespaces, not both.
For more on namespace design, see Deep Agents backends and user-scoped memory.
Test store isolation
Withlanggraph dev running and two test users configured in your auth handler, verify that store data does not leak across users:
Combine with thread isolation
Store isolation and thread isolation solve different problems:
For multi-user agents, configure both. See Make conversations private for thread and run scoping.
See also
- Authentication and access control
- Set up custom authentication
- Make conversations private
- Semantic search in deployments
- LangGraph stores
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

