Each skill invocation runs in a fresh transient container. Read-only rootfs, all Linux capabilities dropped, memory and CPU capped, no network unless you allow it. The container reads input on stdin, writes output to stdout, exits. Nothing leaks between runs. A real boundary, not a V8 flag.
Every container, every run. No opt-in flags.
The container's filesystem is immutable. Only /tmp is writable (64MB tmpfs, mode 1777). A skill can't drop a binary, persist state, or modify libraries between runs.
--cap-drop ALL + --security-opt no-new-privileges. Even if a setuid binary somehow ended up in the image, the kernel won't let it escalate. Runs as a non-root user inside the container.
Default is --network none — no socket access at all. Switch to egress mode to route only through a credential-injecting proxy (Charon, or anything HTTP_PROXY-compatible). open exists but you'll know if you need it.
Memory cap (default 512MB), swap disabled, CPU shares capped (1.0), PIDs capped at 256. A skill can't fork-bomb, RAM-bomb, or steal cycles from the host.
Default 60-second wall-clock cap per invocation. SIGTERM first, SIGKILL on the way out. The Go server docker rm -f on top of --rm so a hung daemon doesn't leak containers.
Container reads invocation input on stdin, calls the named function, writes {"ok": true, "output": ...} to stdout, exits. That's the contract. Implement a runner for any language that fits.
Standalone Go binary + a reference Node 22 runner image.
# Clone + build
$ git clone https://github.com/darklake-ai/chasm
$ cd chasm && go build -o chasm ./cmd/chasm
# Run the HTTP server
$ ./chasm serve --listen 127.0.0.1:8890
The auto-generated access token lands at ~/.chasm/token.
# Pull the published image
$ docker pull ghcr.io/darklake-ai/chasm-node22:latest
# Or build locally from the repo
$ docker build -t chasm-node22 \
$ examples/runners/node22
Python, Bun, Deno runner images are easy to write — they only need to fit the stdin/stdout contract.
Chasm doesn't care what harness called it. The wire protocol is a single endpoint with a JSON body. Fathom, LangChain, CrewAI, custom loops — all the same.
One config block. Fathom builds the same RunRequest it would have built for its subprocess sandbox, but ships it to Chasm.
POST a JSON body to /run. Wraps a Python tool decorator cleanly. Examples in the repo.
chasmclient.New(url, token).Run(ctx, req) — tiny, no transitive deps, ~80 lines.
If your language can do HTTP, you can call Chasm. The contract is documented; no SDK required.
Open source. MIT-licensed. Built to bolt on, not lock in.