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.
| Pattern | Where user scope is set | Best when |
|---|---|---|
| Explicit namespace + deny | Application code puts user_id first in every namespace | You already pass user identity into graph code, or you want namespaces to reflect the full storage path |
| Automatic prefix rewriting | Auth handler prepends ctx.user.identity to logical namespaces | You want simpler agent code and transparent isolation at the API layer |
@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:| Concern | Mechanism | Scopes |
|---|---|---|
| Conversation history | Thread metadata filters (owner) | Per-thread checkpoints and messages |
| Long-term memory | Store namespace rewriting | Cross-thread memories, preferences, and documents |
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.

