Every platform says it takes security seriously. Nobody says it in the breach post-mortem, either — that's when they finally describe the architecture instead of the adjectives. So let's skip to the architecture. The easiest way to explain tenant isolation is to walk through the three ways teams usually get it wrong, and what breaks when they do.
Mistake one: filter by tenant ID in application code
This is the default because it's the obvious thing to write: every query gets a WHERE user_id = ? clause, and as long as every developer remembers it, every request stays inside its own walls. The wreckage shows up later, when the codebase has four hundred endpoints instead of four. Somebody adds a reporting query that joins two tables and forgets the filter on the second one. Somebody else builds an admin tool "just for internal use" that queries without any tenant scoping at all, because it felt safe at the time. Neither mistake trips a test, because the query still returns valid rows — just the wrong tenant's valid rows.
We don't rely on every query remembering to ask politely. Row-level security is enforced at the database layer, so the database itself refuses to return another tenant's rows regardless of what the calling code asked for. There's no privileged bypass sitting in the request path either — the policy applies always, including to the paths we'd be tempted to treat as trusted.
Mistake two: treat the sandbox as an optimization, not a boundary
Agents here execute real code — that's the whole point of the product — and the tempting shortcut is to run that code somewhere convenient and lock it down "if we get to it." The wreckage in this version looks like a compromised dependency pulled in during a build reaching out to the open internet, or one tenant's agent run reading files that belong to a workspace it was never supposed to see, because the filesystem was shared by default and restricted by exception.
Agent workloads run in isolated environments instead:
- Locked-down filesystems.
- Network egress that's an allowlist rather than an open door.
An agent working on your build sees your workspace, full stop. Untrusted code — including builds of your own app — compiles inside containers where the isolation is structural, not a setting someone remembered to flip.
Mistake three: hand the credentials to the agent
This is the subtlest one, and the one I'd guess catches the most teams off guard. If the agent needs to deploy to your host or post to your store, the shortest path is to put the OAuth token or the SSH key in its context and let it use them. It's also the shortest path to disaster: a prompt-injected instruction, a hallucinated action, a credential that ends up sitting in a transcript log somewhere it shouldn't. The agent doesn't have to be malicious for this to go wrong — it just has to be wrong once, with real keys in hand.
So the agent never holds the keys. Connected credentials are stored scoped to your tenant and used only for the action you connected them for:
- Store accounts
- Social OAuth tokens
- Deploy keys
- Google service accounts
When an agent needs to deploy or upload, it asks the platform to do it; the platform holds the credential and performs the action. The agent never sees the secret it's asking to use. And on the analytics side, where Google properties are sometimes shared across sites, every GA4 pull is hostname-filtered so your dashboard can't accidentally show someone else's numbers even when the underlying property collects for many domains.
What actually gets checked before anything ships
Two rules apply everywhere in this platform, and they matter most right here:
- Agents cannot spend your money.
- Agents cannot post as you.
Both of those require your click. It means the worst day any automated component can have still doesn't touch your wallet or your reputation — the blast radius is capped by design, not by the agent's good judgment. Full details on retention and deletion live in the Privacy Policy; deletion requests take effect within 30 days.



