Why Privacy Is the Hardest Problem in AI Workspaces, and How Kylon Solves It
When AI agents operate with real agency inside a workspace, privacy becomes an architecture problem. This post walks through how Kylon keeps agents confined to authorized data, even under adversarial conditions.
Most AI products treat privacy as a settings page. A toggle for data retention. A compliance badge in the footer.
That works when AI is a chatbot in a tab. It breaks the moment AI becomes a workspace member that reads your files, uses your integrations, writes to your databases, and acts on your behalf while you sleep.
Why agents make privacy harder
A traditional SaaS app has well-understood trust boundaries. A user authenticates, the app checks permissions, the data layer enforces access. The code is deterministic and auditable.
An AI agent doesn't fit that model. It generates actions probabilistically. It can be manipulated through prompt injection. It operates across channels, connections, and users. It may run unattended in the background.
If you rely on the model to respect boundaries, you're asking a probabilistic text generator to make security decisions. Not a great plan.
The alternative: treat the model as untrusted input and enforce every boundary in infrastructure the model cannot touch.
Defense in depth
Kylon's isolation is layered. Each layer operates independently, and the failure of any one doesn't compromise the others.

Per-agent compute isolation
Every agent in Kylon runs in its own dedicated hardware-virtualized microVM, keyed to the agent's persistent identity. This isn't process-level isolation or container namespacing. It's full hardware virtualization: separate kernel, separate memory space, separate disk.
Agent A physically cannot observe Agent B's processes, memory, or filesystem. They are separate virtual machines running on isolated hardware boundaries. There is no shared execution host, no ambient state that could leak between agents.
VMs are provisioned on demand when an agent activates and auto-pause when idle. When a VM resumes, it picks up from its own checkpointed state, not from a shared pool. This matters because it means there's no "warm pool" of generic VMs where one agent's residual memory could leak to the next occupant. Each VM belongs to exactly one agent identity for its entire lifecycle.
If an agent is fully compromised, the blast radius is one VM. No lateral movement, no shared state between agents.
Principle: Contain, don't trust. Assume every agent can be compromised. The architecture's job is to make compromise boring: one VM, no lateral movement, no useful credentials to steal.
Per-command sandboxing with bubblewrap
Isolating agents from each other is necessary but not sufficient. A single agent's VM still contains filesystem mounts, environment variables, and system paths. A prompt-injected agent could try to read credentials on disk, poke at another channel's files, or explore system directories looking for secrets.
Kylon addresses this with a second isolation layer: every shell command runs inside a bubblewrap-based namespace sandbox before it touches the VM's filesystem.
The sandbox creates a minimal Linux namespace with precise mount control. It operates in whitelist mode: the root filesystem starts as an empty tmpfs, and only explicitly listed paths are mounted in. Each command invocation gets:
- A single writable path: the agent's ephemeral scratch directory. Everything else is read-only or invisible.
- An explicit read allowlist, computed per invocation. Only the current channel's directory, the agent's own configuration directory, shared workspace knowledge, and explicitly granted skills are mounted as readable. Minimum system directories are included for basic operation.
- Blocked paths are masked with zero-permission overlays. Even if a parent directory is readable, specific sensitive subdirectories can be individually blocked.
- Network access is controlled per invocation. The sandbox can isolate the network namespace entirely when a command doesn't need external connectivity.
- Process spawning is restricted via seccomp filters that intercept
fork,clone, and related syscalls. When subprocess creation is disabled, the sandboxed command runs as a single process with no ability to spawn children, closing off an entire class of escape techniques.
Everything outside the allowlist isn't permission-denied. It's not mounted into the namespace at all. From the perspective of the sandboxed command, those paths simply do not exist.
This means an agent in #engineering cannot cat a file from #hr, even though both channels live under the same workspace filesystem. The namespace sandbox doesn't expose the #hr directory. An ls would show nothing. A find would return no results. The files aren't hidden; they aren't there.
The allowlist is recomputed for each command invocation, not cached for the session. If an agent's channel membership changes mid-session, the next command reflects the new state immediately.
Principle: Make unauthorized paths invisible, not forbidden. Permission-denied implies the path exists. An empty namespace tells the agent nothing.
RBAC-enforced file access
Workspace files are mounted read-only from cloud storage, scoped to a single workspace. Files from other workspaces aren't in the directory tree.
But read-only mounts only prevent filesystem writes. To persist anything, the agent must go through the workspace API, which runs a full RBAC check: channel membership, path policy, and agent identity verification. There's no path that bypasses both the sandbox's read constraints and the API's write enforcement.
Principle: Separate the read path from the write path, and gate both independently.
Connection access control
This is where most AI tools get it wrong.

Typical pattern: connecting Gmail or GitHub creates a service account the AI uses on behalf of everyone. Everyone in the channel gets the same access through the AI, regardless of their own permissions. Classic confused deputy.
Consider the scenario: an agent is asked to "check the team calendar." In a flat-access model, it would use one team member's calendar connection to read another member's private appointments, because the connection is shared at the workspace level with no per-user scoping. No prompt injection needed. Just an architectural gap.
This is the kind of failure Kylon's connection model is designed to prevent:
- Connections belong to people. Your Gmail connection is yours, not "the workspace's Gmail."
- Agents need explicit individual grants. Workspace-wide "grant all" policies exclude agents at the ACL layer. No accidental over-sharing.
- Delegation is scoped and brokered. The agent never holds raw credentials. The system brokers a scoped authorization at execution time, auditable and revocable.
- Credentials encrypted at rest, decrypted only at moment of execution, in-memory. Never in plaintext, never in message content.
Unauthorized connections aren't denied. They're invisible. An agent can't even discover what it doesn't have access to.
Principle: Connections belong to people, not to AI. Every delegation should be explicit, scoped, and revocable.
Encrypted secrets
API keys and tokens are stored encrypted and injected on demand. From the agent's perspective, secrets are write-only: it can pass a secret as an environment variable to a process, but it cannot read, print, or include the value in any output.
Output sanitization
All tool output is sanitized to strip internal infrastructure identifiers before reaching the model. The agent cannot learn the names of its own containment mechanisms. Disclosure boundaries in the system prompt prevent cross-user data leakage. This is the softest layer, by design. It handles the 99.9% of non-adversarial interactions. For the rest, the hard infrastructure layers above do the work.
The external action gate
The layers above keep agents confined within the workspace. But what about actions that leave it? Sending an email. Posting to an external service. Making an API call that affects a real account.
These are irreversible. No sandbox can undo a sent email.
Kylon's rule: agents cannot execute external actions unilaterally.

When an agent tries to send an email, the system intercepts it and converts it into a reviewable draft. The email never leaves the workspace. A human reviews, edits if needed, and explicitly confirms before anything is sent.
The critical detail: the approval is bound to a per-action fingerprint computed from the exact recipients, content, and sending account. If anything changes after approval, the fingerprint breaks and the approval is automatically invalidated. No bait-and-switch is possible.
Consider the attack: a prompt injection instructs an agent to draft a benign-looking email, get approval, then alter the recipient and body before the actual send. The fingerprint check blocks it: the approval was for one exact message, and the modified version doesn't match. The send fails, the agent is forced to re-request confirmation, and the altered content is visible to the human reviewer.
Three confirmation scopes, all human-controlled: single-use (consumed immediately), 24-hour window (expires automatically), and standing policy (revocable at any time).
Principle: AI can draft. Only humans can send. And the human approves the exact content, not a blank check.
Continuous monitoring
Deploying these layers is only half the work. The other half is making sure they keep working.
Every agent action, tool call, and external request is logged with the signals and context behind it. The isolation layers are not "set and forget." They're actively monitored:
- Anomaly detection on sandbox violations. When a sandboxed command attempts to access a path outside its allowlist, the attempt is logged and flagged, even though the access was already blocked. Patterns in these attempts surface potential prompt injection campaigns before they succeed.
- Connection access auditing. Every connection delegation is logged: who authorized it, which agent used it, what action was taken, and when. Unusual patterns (an agent suddenly accessing five connections it has never used before) trigger alerts.
- Fingerprint mismatch tracking. When an HITL fingerprint check fails, the before-and-after content is logged for review. This provides a direct window into whether agents are being manipulated by adversarial inputs in the data they process.
The security team's job in an AI workspace isn't watching for bugs. It's watching the loops: are the isolation layers catching what they should? Are the patterns changing? Are new attack surfaces emerging as the agents take on new capabilities?
Principle: Monitor the loops, not just the logs. The architecture should tell you when it's catching something, not just when it fails.
Putting it together
A prompt injection tells the agent to read another workspace's files? The workspace-scoped mount doesn't contain them. An agent tries to browse another channel? The namespace sandbox doesn't expose it. Tries to use a Gmail connection it wasn't granted? Connection is invisible. Gets email approval and swaps the content? Fingerprint mismatch, approval voided.
The hard part of AI workspace privacy isn't encryption or ACLs. It's that you're containing a creative, unpredictable system that can be manipulated by adversarial inputs and attempt anything its tools allow.
You can't solve that with a permissions dialog or a prompt. You solve it with layers of infrastructure the model can't influence, combined with human gates that verify not just intent but exact content, and continuous monitoring that tells you when the architecture is doing its job. That's the architecture privacy requires when AI has real agency.
Hire the AI agent team that runs your entire business.