Disclosure: BlueBear builds a platform with this access control model, so we have a commercial interest. The five enforcement points are generic; where we quote a specific behaviour it is our own implementation and is named as such.
The short answer: five enforcement points, and the first decides the rest
A workspace boundary is only as strong as the point where it is resolved. Everything downstream — policy, filtering, recording — is enforcing whatever value that first step produced.
| # | Enforcement point | The failure | How to test it |
|---|---|---|---|
| 1 | Resolution — where the boundary comes from | Read from the request body, so the caller chooses it | Send a request naming a boundary the credential does not own. It must fail. |
| 2 | Entry — who may be in the workspace | Membership implied by having a link | Ask what the access modes are and which is the default |
| 3 | Execution — what may run inside it | Enforced in the interface but not at session start | Start a session for a disallowed agent through the API, not the UI |
| 4 | Read — what queries return | Filtering by convention in application code | Ask what happens if a query omits the filter. "It returns everything" is the answer to fear. |
| 5 | Record — what the evidence carries | Boundary derived at read time rather than stored | Ask to see a stored record and look for the boundary on it |
1. Resolution: from the credential, never from the payload
This is the one that undoes everything else, and it is worth stating as a rule you can put in a design document verbatim: a request that can nominate its own tenant is a request that can nominate someone else's.
The boundary must be established from the credential presented when the request is admitted, then carried through every subsequent layer as explicit data rather than as an ambient assumption a later refactor can drop.
Two related properties are worth designing for. First, the credential should itself be scoped to a subject — in our gateway a tenant API key carries a subject type of either the whole tenant or a specific user, so a key issued for one user cannot act as another. Second, crossing a boundary should require a human, not a machine credential: our cross-tenant path is refused unless a platform administrator is behind the session, with a specific error rather than a generic denial, and the audit event for key creation carries an explicit flag recording whether it was cross-tenant. The design intent is that a machine credential structurally cannot become a cross-tenant impersonation path.
2. Entry: an access mode, chosen rather than defaulted
Who may be inside the workspace at all is a distinct question from what they may do there, and it deserves an explicit setting rather than an implication.
Ours is a three-value access mode: visible to its creator only, to their organisation, or to everyone in the tenant. Three values rather than a boolean because the middle case — a team, a department, a client account — is the one that actually occurs and the one a two-value model forces you to fake.
Per-user grants sit inside this and answer a different question. A membership record in our model carries an access level, per-user settings, and usage limits — daily ceilings on tokens, messages and sessions — plus a status and an optional expiry. That last field matters more than it looks: access with an expiry is access somebody has to renew, which is the only mechanism that reliably removes people who no longer need it.
3. Execution: enforced where sessions start, not where buttons are
The characteristic failure here is an access rule that lives in the interface. The dropdown only offers permitted agents, so the rule appears to work — and the API accepts anything.
The requirement is that the list of permitted agents is enforced at every path that binds a conversation or starts a session, not only where a human would choose. In our implementation the workspace carries an allowed-agent list, with an empty list meaning no restriction, enforced at conversation bind and at every session-create path.
The deliberate design decision worth stealing: editing the list affects new bindings only. Live sessions are left to expire rather than being force-stopped, because terminating a turn mid-flight to apply an access change causes a worse failure — partial writes, a confused user, a half-finished workflow — than letting it complete under the previous rule. What matters for review is that the run is recorded as having run under the rule that was in force, so the sequence is reconstructable afterwards.
4. Read: the filter must not be a convention
Nearly every multi-tenant system has a tenant column. The question is what happens when a query forgets it — and the honest answer in most systems is that it returns everything, silently, and nothing fails.
Three mechanisms move this from convention to structure, in increasing order of durability:
- Compound keys. Look up by identifier and boundary together, so a wrong-boundary lookup finds nothing rather than finding the row and relying on a later check. Our workspaces carry a compound uniqueness constraint pairing the workspace identifier with its tenant for exactly this reason, and workspace names are unique within a tenant rather than globally.
- Cascading ownership. Foreign keys that cascade on delete, so removing a boundary removes what belonged to it rather than orphaning it.
- A test that fails when a read path is added without the filter. This is the only one that catches the query somebody adds in a hurry two years from now.
5. Record: the boundary is stored, not derived
The last point is easy to miss because everything appears to work without it.
If the boundary is derived at read time — worked out by joining back to something else — then the answer depends on the query, and "we can filter records by customer" is a weaker statement than "the record says which customer". The second is what lets you export one customer's history, prove separation, and scope an incident by boundary.
The related discipline is on identity records: our tenant API keys carry a database-level partial unique index enforcing one active key per tenant and subject, rather than an application check that reads and then writes and can race. A structural guarantee holds under concurrency; an application check holds under review.
Capabilities, and why revoking one should not reach backwards
One design decision from our own implementation is worth naming because it is easy to get wrong in the other direction.
Capabilities granted to a tenant — the ability to run a compliance-managed workspace, for instance — gate future use when revoked. Revoking blocks new workspaces of that kind; it does not retroactively downgrade a workspace that already exists and is already enforcing those rules. The reasoning is that silently weakening a guarantee something is already relying on is worse than leaving a grant in place until it is deliberately unwound.
That is a genuine trade-off rather than an obvious answer, and it is the kind of decision worth asking any vendor to state, because whichever way they answer it tells you how they think about the boundary.
If you operate in a regulated industry
Add a sixth point: the compliance regime attaching to the workspace rather than the account, so one part of the business can run under stricter rules without imposing them everywhere. And check the fail-closed behaviour explicitly — a compliance dependency that cannot be reached should stop the action. Audit trails for financial services covers the evidence obligations that sit on top.
If you are a platform or engineering lead
Point 4 is where to spend the effort, because it is the one where a correct system quietly becomes an incorrect one over time without anybody making a decision. A failing test is worth more than a code review convention. Multi-tenant AI agent isolation on Kubernetes is the existing runtime treatment.
If you resell this to customers
Point 5 is the one your contracts depend on. Without the boundary on the record you cannot export one customer, cannot scope an incident to the customers affected, and cannot answer a data request without touching everyone. White-label brand workspaces explained covers the reseller structure.
Do this next
Run test 1. Send an authenticated request that names a boundary the credential does not own, and see what comes back. It takes ten minutes and it is the only one of the five that, if it fails, makes the other four irrelevant. Then read what a secure workspace boundary is if you need to explain the model to colleagues, or least privilege for AI agents for the credential scoping inside it.
Questions people actually search for
- workspace boundary security
Boundary security is decided at five points: where the boundary is resolved from, whether policy is evaluated inside it, whether read paths are filtered by it, whether records carry it, and whether it survives every layer the request passes through. The first decides the rest - if the boundary comes from anything the caller can set, the other four are enforcing a value the caller chose. Establish it from the credential presented at admission and carry it as data, never as an ambient assumption.
- workspace boundary access control
Three questions, in order. Who may enter the workspace at all - an access mode saying whether it is visible to its creator, their organisation, or everyone in the tenant. What may run inside it - which agents are permitted to bind, enforced at every session-start path rather than only in the interface. And what may be done with what is inside - read, write and download treated as separate authorities rather than one permission. Most models cover the first and are vague about the third.
- how do you enforce tenant isolation in an ai platform
Push it into the data model rather than the service layer. Compound uniqueness constraints that include the tenant, foreign keys that cascade on delete, and lookups keyed on the identifier and the tenant together so a wrong-tenant query finds nothing rather than finding the row and relying on a later check. Application-level filtering is necessary and insufficient: it is correct until someone adds a query in a hurry, and nothing fails loudly when they do.
- should ai agent permissions be per user or per workspace
Both, and they answer different questions. The workspace decides what is possible there - which agents, which connections, which compliance rules. The user grant decides what that person may do inside it. Collapsing them into one model produces either a workspace so permissive it is not a boundary, or per-user rules so detailed nobody maintains them. The workspace should be the coarse, durable boundary and the user grant the finer, changeable one.
- what happens when you change an ai agent access list
It should affect new bindings rather than running work, and that should be a stated decision rather than an accident. Terminating a turn that is mid-flight to apply an access change usually causes a worse failure than letting it finish - partial writes, a confused user, a half-completed workflow. The defensible design is that the change takes effect at the next bind and that the in-flight run is recorded as having run under the previous rule.