fix(deepagents): scope StoreBackend ls/glob/grep to exact namespace (#772) - #796
Conversation
|
harikeshdev76-ux is attempting to deploy a commit to the LangChain Team on Vercel. A member of the Team first needs to authorize it. |
|
There was a problem hiding this comment.
Pull request overview
This PR fixes a namespace-isolation bug in StoreBackend where ls/glob/grep could return (and grep could expose) files from sibling namespaces that share a string prefix, by filtering paginated store.search() results down to items in the backend’s exact namespace. It also adds a regression test to validate isolation between sibling namespaces (e.g. ["tenant","acme"] vs ["tenant","acme-corp"]).
Changes:
- Added an exact-namespace equality helper and used it to filter results accumulated by
searchStorePaginated(). - Ensured
ls/glob/grep(and any other callers ofsearchStorePaginated) only operate on items in the backend’s exact namespace. - Added a regression test covering sibling-prefix namespaces to prevent future leakage.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| libs/deepagents/src/backends/store.ts | Filters store.search() pagination results to items whose namespace exactly matches the backend namespace to prevent sibling-prefix leakage. |
| libs/deepagents/src/backends/store.test.ts | Adds a regression test to confirm ls/glob/grep don’t leak results across sibling namespaces with shared prefixes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| /** | ||
| * Deep-equality check for two store namespaces. | ||
| */ | ||
| function namespacesEqual(a: string[] | undefined, b: string[]): boolean { | ||
| if (!a || a.length !== b.length) return false; |
| describe("StoreBackend namespace isolation", () => { | ||
| it("ls/glob/grep only see the backend's exact namespace, not sibling prefixes (#772)", async () => { | ||
| const { runtime } = makeConfig(); |
deepagents-acp
deepagents
@langchain/sandbox-standard-tests
@langchain/daytona
@langchain/deno
@langchain/modal
@langchain/node-vfs
@langchain/quickjs
commit: |
Summary
StoreBackendis pinned to a single namespace, but its listing operations (ls,glob,grep) query the underlying store withstore.search(namespace), which matches by namespace prefix. Sibling namespaces that share a leading string — e.g.["tenant","acme"]and["tenant","acme-corp"]— leak into each other: one backend'sls/glob/grepreturns (andgrepprints the line contents of) the other's files, even thoughread/writecorrectly use exactget/put.Fixes #772.
Root cause
searchStorePaginated()accumulates every item returned bystore.search(namespace). Because that search is a prefix match, items from sibling namespaces are included.read/readRaw/writego throughget/put, which match the namespace exactly — which is why the same backend will list andgrepa file that it then refuses toread.Fix
Filter the paginated search results down to items whose namespace is exactly the backend's namespace, via a small
namespacesEqualhelper. AStoreBackendnever nests files into sub-namespaces (the file path lives in the item key), so exact-namespace matching is the correct invariant. This repairsls,glob, andgrepin one place, since all three build their file set fromsearchStorePaginated.Test
Added a regression test (
StoreBackend namespace isolation) that mounts two sibling-prefix backends on one store and assertsls/glob/grepeach see only their own namespace, while the sibling still sees its own file.