Run agents securely, at scale.

Isolated sandboxes for agents and code, running inside your own cloud.

pip install chalkcompute
hello_sandbox.py
from chalkcompute import Image, Sandbox

sandbox = Sandbox(
    image=Image.debian_slim("3.12"),
    lifetime="600s",
).run()

result = sandbox.exec("python", "-c", "print('Hello, World!')")
print(result.stdout_text)
sandbox.terminate()
curl -s -L https://api.chalk.ai/install.sh | sh
terminal
# A sandbox that can reach only api.github.com
chalk sandbox create -i python:3.12 -n pr-bot \
  --host api.github.com \
  --resource-detection github-pull-requests

# Launch Claude Code in a tmux session, then reattach later
chalk sandbox start coding_agent_sandbox --tmux -- claude
chalk sandbox attach
Whatnot logo
Socure logo
Sunrun logo
Grindr logo
Turo logo
MoneyLion logo
Melio logo
Mission Lane logo
Medely logo
Iwoca logo
Nowsta logo
Apartment List logo
Pipe logo

Isolated, governed, stateful. Sandboxes for agents that touch production.

  • Your cloud accountgVisor user-space kernelAgent code · own fs, net, pid

    Kernel-level isolation

    Every sandbox runs behind a gVisor user-space kernel with its own file system, network and process namespaces.

  • pypi.orgallowapi.anthropic.comallow + key169.254.169.254denypaste.example.netdeny

    Network policy on egress

    Name the hostnames, CIDRs and ports a sandbox may reach. The rest are blocked.

  • Snapshot · memory + fsFORKSBX-A1F3FORKSBX-7C02FORKSBX-E9D4FORKSBX-40BB

    Snapshot and fork running agents

    Chalk snapshots the running sandbox and restores it, with the same files and the same in-memory state, in seconds.

Explore Chalk Sandboxes. Exec, volumes, and network policy from Python.

  • Run commands easily inside Chalk sandboxes.

  • Mount durable, versioned volumes to share data between runs and sandboxes without baking it into the image.

  • Allow exact hosts, CIDR ranges and ports. Inject a Chalk Secret into matching requests at egress.

exec.py
from chalkcompute import Image, Sandbox

sandbox = Sandbox(
    image=Image.debian_slim("3.12").workdir("/app"),
    name="hello-sandbox",
).run()

result = sandbox.exec("ls", "-la", "/app", timeout_secs=30)
print(result.stdout_text)
print(result.stderr_text)
print(result.exit_code)

# Streaming output: sandbox.exec_stream(...)
# Interactive stdin and signals: sandbox.exec_start(...)

sandbox.terminate()
volumes.py
from chalkcompute import Image, Sandbox, Volume

vol = Volume("training-data")
vol.put_file("inputs/example.txt", b"hello\n")

sandbox = Sandbox(
    image=Image.debian_slim("3.12"),
    name="volume-reader",
    volumes=[("training-data", "/data")],
).run()

result = sandbox.exec("cat", "/data/inputs/example.txt")
print(result.stdout_text)  # "hello\n"

sandbox.terminate()
policy.py
from chalkcompute import Image, NetworkPolicy, Sandbox, Secret

sandbox = (
    Sandbox(
        image=Image.debian_slim("3.12"),
        network_policy=NetworkPolicy(
            allowed_hosts=["pypi.org", "files.pythonhosted.org"],
            denied_routes=["169.254.169.254/32"],
        ),
    )
    # The proxy adds the key on the way out; the sandbox never sees it.
    .add_credentials("api.anthropic.com", Secret.from_chalk_env("ANTHROPIC_API_KEY"))
    .run()
)

More than a sandbox. The runtime long-running agents need.

  • Snapshots

    Save a running sandbox, memory and file system included, and restore it as many times as you need. Each restore is a new sandbox.

  • Suspend and restore

    Release the compute while an agent waits. Restore brings back the same sandbox id or fork with a new ID.

  • Stateful by design

    Run for hours or days. Sandboxes can restart and pick up from a volume.

  • CPU and GPU host pools

    Choose a GPU type, and keep hosts warm or scale them to zero.

  • Versioned volumes

    Every commit is an immutable version. Fork a volume into a new lineage without copying data.

Agent sandboxes

Agents running on Chalk today.

Each of these is a live demo, with code you can deploy. Pick one to see what it runs and exactly what its sandbox can reach.

Coding agents

  • Provision a private repo checkout, launch Claude Code in tmux, detach, and reconnect later. Pull requests it opens are recorded.

    Watch the walkthrough
  • The Pi coding agent works on a public GitHub repo in a sandbox that can reach GitHub and the model gateway and nothing else.

    Try it live
  • Reviews a public pull request in a sandbox limited to the model gateway. You inspect the comments before anything is posted.

    Try it live
  • An agent builds a small web app and tests it inside its sandbox before you see the result.

    Try it live
sketch.py
image = (Image.sandbox()
    .with_claude_code("2.1.270", trusted_dirs=["/workspace/repo"])
    .with_gh().with_tmux().workdir("/workspace/repo"))
sandbox = (Sandbox(image=image, cpu="2", memory="16Gi",
        chalk_identity=True,
        resource_detectors=[ResourceDetector.GITHUB_PULL_REQUESTS])
    .add_credentials("api.anthropic.com",
        Secret.from_chalk_env("CLAUDE_CODE_OAUTH_TOKEN"))
    .run())
sketch.py
policy = NetworkPolicy(allowed_hosts=[
    "github.com", "*.github.com",   # the wildcard skips the apex
    "api.chalk.ai",                  # model gateway
])
sketch.py
# the diff goes in as a file; the agent can only talk to the model
policy = NetworkPolicy(allowed_hosts=["api.chalk.ai"])
sandbox = Sandbox(image=review_image, network_policy=policy).run()
sandbox.exec("python", "review.py", "/workspace/pr.diff")
sketch.py
result = sandbox.exec("npm", "test", timeout_secs=120)
# reach the dev server from your machine:
#   chalk sandbox configure-ssh && ssh -L 3000:localhost:3000 chalk-sbx-<name>
sketch.py
sandbox = Sandbox(image=desktop_image, cpu="2", memory="4Gi",
                  network_policy=NetworkPolicy(allowed_hosts=[])).run()
sketch.py
policy = NetworkPolicy(allowed_hosts=["inference.example.internal"])
sandbox = Sandbox(image=hermes_image, network_policy=policy).run()
sketch.py
notion = NetworkPolicy.Rule(transforms=[NetworkPolicy.Transformer(
    headers={"Authorization": "Bearer __chalk_secret_N"},
    headers_secrets={"__chalk_secret_N": "NOTION_READONLY_TOKEN"})])
policy = NetworkPolicy(allowed_hosts={"api.notion.com": [notion]})
sketch.py
# tools come through your org's MCP gateway; no tokens in the sandbox
sandbox = Sandbox(image=sre_image, chalk_identity=True).run()

Data and ops agents

  • Nous Research's Hermes gets a full shell that can reach only its model endpoint. Every other connection is refused.

    Watch the walkthrough
  • Answers with numbers from ChalkSQL and context from Notion and Linear, each through scoped credentials the agent never holds.

    Watch the walkthrough
  • A recorded investigation of a fictional incident through MCP tools, ending in a rollback request that waits for a human.

    Watch the walkthrough
sketch.py
image = (Image.sandbox()
    .with_claude_code("2.1.270", trusted_dirs=["/workspace/repo"])
    .with_gh().with_tmux().workdir("/workspace/repo"))
sandbox = (Sandbox(image=image, cpu="2", memory="16Gi",
        chalk_identity=True,
        resource_detectors=[ResourceDetector.GITHUB_PULL_REQUESTS])
    .add_credentials("api.anthropic.com",
        Secret.from_chalk_env("CLAUDE_CODE_OAUTH_TOKEN"))
    .run())
sketch.py
policy = NetworkPolicy(allowed_hosts=[
    "github.com", "*.github.com",   # the wildcard skips the apex
    "api.chalk.ai",                  # model gateway
])
sketch.py
# the diff goes in as a file; the agent can only talk to the model
policy = NetworkPolicy(allowed_hosts=["api.chalk.ai"])
sandbox = Sandbox(image=review_image, network_policy=policy).run()
sandbox.exec("python", "review.py", "/workspace/pr.diff")
sketch.py
result = sandbox.exec("npm", "test", timeout_secs=120)
# reach the dev server from your machine:
#   chalk sandbox configure-ssh && ssh -L 3000:localhost:3000 chalk-sbx-<name>
sketch.py
sandbox = Sandbox(image=desktop_image, cpu="2", memory="4Gi",
                  network_policy=NetworkPolicy(allowed_hosts=[])).run()
sketch.py
policy = NetworkPolicy(allowed_hosts=["inference.example.internal"])
sandbox = Sandbox(image=hermes_image, network_policy=policy).run()
sketch.py
notion = NetworkPolicy.Rule(transforms=[NetworkPolicy.Transformer(
    headers={"Authorization": "Bearer __chalk_secret_N"},
    headers_secrets={"__chalk_secret_N": "NOTION_READONLY_TOKEN"})])
policy = NetworkPolicy(allowed_hosts={"api.notion.com": [notion]})
sketch.py
# tools come through your org's MCP gateway; no tokens in the sandbox
sandbox = Sandbox(image=sre_image, chalk_identity=True).run()

Computer use

  • Claude drives a GNOME desktop and OpenOffice inside a sandbox with no network. Screenshots and clicks never leave the box.

    Try it live
sketch.py
image = (Image.sandbox()
    .with_claude_code("2.1.270", trusted_dirs=["/workspace/repo"])
    .with_gh().with_tmux().workdir("/workspace/repo"))
sandbox = (Sandbox(image=image, cpu="2", memory="16Gi",
        chalk_identity=True,
        resource_detectors=[ResourceDetector.GITHUB_PULL_REQUESTS])
    .add_credentials("api.anthropic.com",
        Secret.from_chalk_env("CLAUDE_CODE_OAUTH_TOKEN"))
    .run())
sketch.py
policy = NetworkPolicy(allowed_hosts=[
    "github.com", "*.github.com",   # the wildcard skips the apex
    "api.chalk.ai",                  # model gateway
])
sketch.py
# the diff goes in as a file; the agent can only talk to the model
policy = NetworkPolicy(allowed_hosts=["api.chalk.ai"])
sandbox = Sandbox(image=review_image, network_policy=policy).run()
sandbox.exec("python", "review.py", "/workspace/pr.diff")
sketch.py
result = sandbox.exec("npm", "test", timeout_secs=120)
# reach the dev server from your machine:
#   chalk sandbox configure-ssh && ssh -L 3000:localhost:3000 chalk-sbx-<name>
sketch.py
sandbox = Sandbox(image=desktop_image, cpu="2", memory="4Gi",
                  network_policy=NetworkPolicy(allowed_hosts=[])).run()
sketch.py
policy = NetworkPolicy(allowed_hosts=["inference.example.internal"])
sandbox = Sandbox(image=hermes_image, network_policy=policy).run()
sketch.py
notion = NetworkPolicy.Rule(transforms=[NetworkPolicy.Transformer(
    headers={"Authorization": "Bearer __chalk_secret_N"},
    headers_secrets={"__chalk_secret_N": "NOTION_READONLY_TOKEN"})])
policy = NetworkPolicy(allowed_hosts={"api.notion.com": [notion]})
sketch.py
# tools come through your org's MCP gateway; no tokens in the sandbox
sandbox = Sandbox(image=sre_image, chalk_identity=True).run()

Built to run untrusted code. All in your own cloud.

  1. 01

    Agent code never sees a shared secret

  2. 02

    Runs in your cloud

  3. 03

    Per-sandbox identity

Network policy

Decide exactly what a sandbox can reach.

Turn destinations on and off, and watch the policy and the agent's traffic change. Anything not on the list is blocked, and denied routes always win.

Allowed destinations
Allowed destinations
policy.py
from chalkcompute import NetworkPolicy, Sandbox

anthropic_key = NetworkPolicy.Transformer(
    headers={"x-api-key": "__chalk_secret_KEY"},
    headers_secrets={"__chalk_secret_KEY": "ANTHROPIC_API_KEY"},
)  # the sandbox never receives the key

policy = NetworkPolicy(
    allowed_hosts={
        "github.com": [NetworkPolicy.Rule(transforms=[git_token])],
        "pypi.org": [],
        "files.pythonhosted.org": [],
        "api.anthropic.com": [NetworkPolicy.Rule(transforms=[anthropic_key])],
    },
    denied_routes=["169.254.169.254/32"],
)

sandbox = Sandbox(image=agent_image, cpu="2", memory="4Gi",
                  network_policy=policy, chalk_identity=True).run()
Agent traffic · sbx-7f3a
  1. allow+keygit clone https://github.com/acme/billinggithub.com is allowed; the proxy adds the token
  2. allowGET https://pypi.org/simple/pandas/pypi.org is allowed
  3. allow+keyPOST https://api.anthropic.com/v1/messagesallowed; the proxy adds x-api-key from a Chalk Secret
  4. denyTCP 10.0.4.12:5432 (postgres read replica)no route allows 10.0.0.0/8
  5. denyGET http://169.254.169.254/computeMetadata/v1/denied_routes overrides every allow
  6. denyPOST https://exfil.example.net/uploadnot on the allowlist; default deny
TestimonialsGrindr logo
The only integrated compute and context engine that ran entirely inside our own environment.
AJ BalanceCPO, Grindr

Agents your CISO approves.

Bring one agent use case. We'll deploy sandboxes in your account and walk your security team through the review.