Weld the Tenant Boundary on the Server
Subtitle: A reported name can be noted. It cannot be trusted blindly.
2026-10-01
In a multi-tenant system, the cheap path is: the request path names an org, the token names an org, and the model passes an org again when it calls a tool. If the three agree, the data is treated as belonging to that tenant.
All three can be swapped. The path can point at someone else's org. The claim in the token can be only a hint. The model can fill in a different repo in its arguments. The cheap path treats "who reported the name" as "whose data this is."
This piece is only about how data is isolated. The per-layer rules and examples stay in the reference draft. They are not repeated here.
Binding happens on the server
A request may name an org, a project, and a repo. The claim in the token is only a hint. What counts is that the server finds "this person is actually a member of that scope," and only after that row comes back does it mint the context for this request.
Business code must not mint that context by hand. Minting happens at the entrance. Later functions take the context. They do not take identifier strings from the caller.
Org, project, repo, index, object key, and topic supplied inside a model tool call are dropped and written back from the context. If the model disagrees with the context, write an audit row and still execute against the context. Do not keep the model's value as a fallback.
Every data plane gets its tenant filter from the server. Tenant fields in the client, the URL, and the model arguments are not used.
The convenient leak is on the corpus
Two repos inside one org reading each other is a common leak in a coding assistant. Isolating business data such as orders by org does not stop this plane. Vectors, code objects, search, and repo caches have to be isolated by org and repo together. One tenant id pushed through every layer makes those two repos share one corpus.
The other cheap path is to check the token and skip the membership lookup, or to let a repo name in the tool arguments override the context. That implementation has to fail a negative test: cross tenants once on purpose, and the detector must catch it. A fully green suite does not show that the detector is wired in.
What this piece does not cover
How keys are generated, where they live, and how they rotate are not here. Whether the model vendor keeps prompts, or trains on them, is not here either.
Making ciphertext in backups unreadable, and actually deleting data on the vendor side, each needs its own procedure. This piece stops at: delete online data inside the scope the server already bound, and record the vendor's ticket number for the deletion request. The contract, zero-retention, and which region the data sits in are not spelled out.
Conclusion
People weld the tenant on the server: bind only after the membership check, and drop the names reported by the client and the model. The convenient leak is two repos in one org sharing a corpus, or letting the caller name the tenant. Keys and vendor retention are not in this piece.
Top comments (0)