Run agents securely, at scale.
Isolated sandboxes for agents and code, running inside your own cloud.
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()# 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 attachIsolated, governed, stateful. Sandboxes for agents that touch production.
Kernel-level isolation
Every sandbox runs behind a gVisor user-space kernel with its own file system, network and process namespaces.
Network policy on egress
Name the hostnames, CIDRs and ports a sandbox may reach. The rest are blocked.
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.
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()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()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.
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 walkthroughThe 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 liveReviews a public pull request in a sandbox limited to the model gateway. You inspect the comments before anything is posted.
Try it liveAn agent builds a small web app and tests it inside its sandbox before you see the result.
Try it live
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())policy = NetworkPolicy(allowed_hosts=[
"github.com", "*.github.com", # the wildcard skips the apex
"api.chalk.ai", # model gateway
])# 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")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>sandbox = Sandbox(image=desktop_image, cpu="2", memory="4Gi",
network_policy=NetworkPolicy(allowed_hosts=[])).run()policy = NetworkPolicy(allowed_hosts=["inference.example.internal"])
sandbox = Sandbox(image=hermes_image, network_policy=policy).run()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]})# 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 walkthroughAnswers with numbers from ChalkSQL and context from Notion and Linear, each through scoped credentials the agent never holds.
Watch the walkthroughA recorded investigation of a fictional incident through MCP tools, ending in a rollback request that waits for a human.
Watch the walkthrough
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())policy = NetworkPolicy(allowed_hosts=[
"github.com", "*.github.com", # the wildcard skips the apex
"api.chalk.ai", # model gateway
])# 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")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>sandbox = Sandbox(image=desktop_image, cpu="2", memory="4Gi",
network_policy=NetworkPolicy(allowed_hosts=[])).run()policy = NetworkPolicy(allowed_hosts=["inference.example.internal"])
sandbox = Sandbox(image=hermes_image, network_policy=policy).run()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]})# 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
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())policy = NetworkPolicy(allowed_hosts=[
"github.com", "*.github.com", # the wildcard skips the apex
"api.chalk.ai", # model gateway
])# 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")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>sandbox = Sandbox(image=desktop_image, cpu="2", memory="4Gi",
network_policy=NetworkPolicy(allowed_hosts=[])).run()policy = NetworkPolicy(allowed_hosts=["inference.example.internal"])
sandbox = Sandbox(image=hermes_image, network_policy=policy).run()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]})# 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.
- 01
Agent code never sees a shared secret
- 02
Runs in your cloud
- 03
Per-sandbox identity
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.
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()- allow+keygit clone https:/
/ github.com/ acme/ billinggithub.com is allowed; the proxy adds the token - allowGET https:/
/ pypi.org/ simple/ pandas/ pypi.org is allowed - allow+keyPOST https:/
/ api.anthropic.com/ v1/ messagesallowed; the proxy adds x-api-key from a Chalk Secret - denyTCP 10.0.4.12:5432 (postgres read replica)no route allows 10.0.0.0/8
- denyGET http:/
/ 169.254.169.254/ computeMetadata/ v1/ denied_routes overrides every allow - denyPOST https:/
/ exfil.example.net/ uploadnot on the allowlist; default deny
The only integrated compute and context engine that ran entirely inside our own environment.
Agents your CISO approves.
Bring one agent use case. We'll deploy sandboxes in your account and walk your security team through the review.