Run a coding agent headless, on your own API key.
A long task shouldn't stop when you close the laptop. Here are three ways to keep Claude Code, Codex or Gemini CLI working without you, what each costs you to set up, and how to keep your API key out of the agent's reach.
All three CLIs run without a terminal to type in.
Each takes the task as an argument, works until it is done, and prints the result. That is what lets it run where nobody is watching.
Nobody is there to approve a command, so decide up front what the agent may do on its own. Each CLI has a flag for it:
- Claude Code: --permission-mode, or --allowedTools to name the tools it may use without asking.
- Codex: --sandbox, one of read-only, workspace-write or danger-full-access.
- Gemini CLI: --approval-mode, one of default, auto_edit, yolo or plan.
- Each also has a flag that skips every check. Use it only where the agent can't reach anything you'd miss: Codex's own help says its flag is for environments that are sandboxed from the outside.
Somewhere for it to keep running.
Headless mode stops the agent waiting for you. It still stops when the machine sleeps. So the agent has to run on a machine that stays on.
A machine that stays on, and a session that outlives your connection.
Rent a small server or use a desktop at home. Install the CLI and your toolchain, clone the repository, and set up git access. Start a tmux session, run the agent in it, and detach with Ctrl-b then d. Close the laptop. Reattach later from anywhere you can SSH from.
A machine to keep on and patched, and all of its setup is yours. The agent runs as you there, so it can read whatever you can, including your key. Two tasks at once need two checkouts, or they share one working tree.
The same, with a wall around the agent.
Build an image with the CLI and your toolchain, mount only the repository, and run the agent headless inside it. A container per task keeps tasks apart. The container still needs a host that stays on, so this sits on top of option 1 or a machine like it.
An image to write and rebuild when your stack changes, and a habit of starting one container per task. The container can't see the rest of the host, but it still sees anything you pass into it, and an environment variable is passed in.
Somebody else runs the machine.
A service starts a machine per task, runs the agent, and keeps the transcript for you to read later. You describe the task and leave.
The least setup, and the most trust: the service sees your code and the transcript. Ask where the machine runs, who holds your API key, and what the agent can reach from inside.
Keep the key out of the agent's reach.
- If your key is in the agent's environment or in a file it can read, the agent can read it. It runs shell commands, so it can print the key, log it, or commit it by mistake.
- At the least, make a key for this use alone, set a spend limit on it if your provider offers one, and revoke it when you stop. Keep it out of the repository and your shell history.
- Know where your CLI keeps the key. Codex, for example, reads it once from stdin with codex login --with-api-key and saves it for later runs, so it is on that machine's disk from then on.
- To keep the key off the machine altogether, put a proxy in front of the provider. The proxy holds the key, the machine holds an address and a placeholder, and the proxy checks each request before it adds the key. Claude Code reads ANTHROPIC_BASE_URL, so it can be pointed at one; check your CLI's documentation for the same setting.
A workspace per task, on your compute, with your key kept outside it.
smedja is option 3, on your own compute.
- Bring your own agent: Claude Code, Codex or Gemini.
- Claude Code runs on an Anthropic API key, Codex on an OpenAI API key, and Gemini on an AI Studio API key. Model usage is billed to your key by your provider, and smedja never bills you for tokens.
- Each task gets its own workspace: its own checkout, disk and shell.
- Workspaces run on your own compute: a Docker Sandboxes account, or your own Linux machine with Docker.
- On Docker Sandboxes, the workspace runs somewhere else, so closing the tab or the lid stops nothing. On your own machine, it keeps going while that machine stays on.
- Send a message and walk away. If the workspace is still starting, the message waits and is delivered when it's up.
- Your key never enters the workspace. Model requests go through a proxy, the workspace holds a placeholder, and every request is checked.
Already run an agent on your own API key?
We're asking a small group of developers who do to try smedja on a real task in their own repository. We review each request and choose a small group. Asking doesn't guarantee a place.