# Sandbox Isolation
source: https://docs.chalk.ai/docs/sandboxes/isolation

## How Chalk isolates sandboxes with gVisor, separates tenants, and restricts kernel access.

These controls also apply to higher-level abstractions like
Scaling Groups, which share the same isolation
primitives.

### Isolation with gVisor

Every sandbox runs under gVisor, a container runtime that intercepts
application system calls through a user-space kernel. Unlike traditional containers that share
the host kernel directly, gVisor interposes a second layer of defense:

```
┌────────────────────────┐
│   Application process  │
├────────────────────────┤
│   gVisor (Sentry)      │  ← intercepts syscalls
├────────────────────────┤
│   Host kernel          │
└────────────────────────┘
```

This means a kernel exploit in one sandbox cannot compromise the host or other sandboxes.
gVisor also restricts the set of available syscalls, reducing the attack surface exposed
to untrusted code — particularly important for agent workloads that execute LLM-generated
commands.

Each sandbox additionally receives its own:

- Filesystem namespace. The root filesystem is ephemeral and private. Persistent storage is available through Volumes.
- Network namespace. Sandboxes have isolated network stacks. Outbound access is allowed by default; attach a network policy to restrict destinations.
- PID namespace. Processes inside a sandbox cannot see or signal processes in other sandboxes.

### Multi-tenancy

Chalk enforces tenant isolation at every layer of the stack:

| Layer          | Mechanism                                                                                                                                                        |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Runtime**    | gVisor kernel-level syscall interception per sandbox                                                                                                             |
| **Network**    | Separate network namespace per sandbox; no shared listening sockets                                                                                              |
| **Storage**    | Volumes are scoped to the owning environment; cross-tenant access is impossible                                                                                  |
| **Scheduling** | Workloads from different tenants are placed on separate host nodes by default                                                                                    |
| **Identity**   | A sandbox created with `chalk_identity=True` receives its own [workload identity](/docs/workload-settings/workload-identity); no two sandboxes share credentials |

For deployments with strict regulatory requirements, dedicated node pools can be
configured so that a tenant's workloads never share physical hardware with any
other tenant.

### Kernel hardening

Sandboxes restrict the syscalls and host access available to the workload
by default. Control this with security_policy:

```
from chalkcompute import ContainerSecurityPolicy, Image, KernelPolicy, Sandbox

sandbox = Sandbox(
    image=Image.debian_slim(),
    security_policy=ContainerSecurityPolicy(kernel_policy=KernelPolicy.RESTRICTED),
).run()
```

kernel_policy is KernelPolicy.RESTRICTED (the default, both when
security_policy is omitted and when set explicitly) or KernelPolicy.OPEN,
which relaxes the sandboxing controls RESTRICTED enables. Use OPEN only for
workloads that need syscalls or host access that RESTRICTED blocks.

OPEN works only on the k8s compute class.





