Running an AI agent on your own computer
How to give an AI agent real access to your machine, decide what it can write and where it can connect, and stop one bad session becoming a bad week.
on this page · 0 / 0 checked
At some point you stop wanting the AI to describe the work and start wanting it to do the work. That means letting a program on your laptop edit files, run shell commands, install packages and open network connections, on the same disk where your SSH keys, your client work and your password-manager exports live. The tools are built for exactly this. Claude Code, OpenAI’s Codex and Google’s Antigravity CLI all run on your machine and all execute commands there [1] [4] [6].
The setup that makes an agent useful is the same setup that makes it expensive when it goes wrong, and the difference between the two is a handful of settings most people never open. Two of them contain an agent, one of them only interrupts it, and the tiring one is the one people switch off first. None of it solves prompt injection. What follows is for one person running an agent on their own machine; if you are deploying to a team, the same settings exist as administrator policy [2] [5], and that is a different job.
The agent is local, the model usually is not
The phrase “local agent” describes where the hands are, not where the thinking happens. The loop runs on your machine, but the decisions come from a model at a vendor’s data centre, and the material the agent reads goes with the request. Anthropic states this without hedging: “Isolation also does not change what is sent to the model. Your prompts and the files Claude reads are transmitted to the Anthropic API or your configured provider with or without a sandbox” [3].
That matters because confidentiality and safety are separate problems and sandboxing only addresses the second one. If your reason for wanting a local agent is that certain files must not leave the building, no permission setting delivers that. Only running the model itself locally does.
That path exists and it is cheap to try. Ollama publishes OpenAI’s open-weight gpt-oss models under an Apache 2.0 licence, both with a 128K context window: the 20B version is a 14GB download and the 120B version is 65GB [8]. The mixture-of-experts weights are quantised to 4.25 bits per parameter in the MXFP4 format, which Ollama says “enables the smaller model to run on systems with as little as 16GB memory, and the larger model to fit on a single 80GB GPU” [8]. You can point an agent harness at it rather than at a cloud endpoint; Ollama documents launching Claude Code against the model with ollama launch claude --model gpt-oss [8].
The honest caveat is that a model you can fit on one machine is not the model the same harness calls by default, and agent work punishes weakness in a specific way: a mistake in step 4 of a long task quietly poisons steps 5 through 12. Run your own real task through it before you decide, and keep the comparison to tasks you actually do.
Two boundaries do almost all the work
Strip away the interface differences and every one of these tools is enforcing two things: which files a command can write, and which hosts a command can reach.
The write boundary is narrow by default and reasonable. In Claude Code, sandboxed commands can write to “the current working directory, the session temp directory, and any directories you’ve added” with --add-dir [1]. Codex calls its equivalent workspace-write, “the default low-friction mode for local work” [4], where the workspace “includes the current directory and temporary directories like /tmp” [5]. Codex also holds paths read-only inside that writable root: <writable_root>/.git, .agents and .codex, with the protection applied recursively, so a command running in the workspace cannot rewrite the repository’s git directory [5].
The read boundary is much wider than people assume, and this is the part worth reading twice. Claude Code’s sandbox documents its default read behaviour as “read access to the entire computer, except certain denied directories”, and adds that this “still allows reading credential files such as ~/.aws/credentials and ~/.ssh/” [1]. A tight write boundary does nothing about that on its own. What contains it is the second boundary: the network. Claude Code “pre-allows no domains by default” and prompts the first time a command needs a new one [1]. Codex is blunter still: “By default, the agent runs with network access turned off” [5].
Anthropic’s own summary of why you need both is the clearest sentence in any of these documents: “Effective sandboxing requires both filesystem and network isolation. Without network isolation, a compromised agent could exfiltrate sensitive files like SSH keys” [1]. One boundary without the other is half a control.
Check which of these your tool applies before you trust the default, because not every tool starts with one. Google’s Antigravity CLI ships its terminal sandbox switched off: enableTerminalSandbox is documented as a boolean with default: false, and you turn it on in settings.json or with the --sandbox flag [6]. Switched on, it is stricter than the other two where it counts. Files such as ~/.ssh and .env are blocked, “anything not explicitly mounted is invisible inside the sandbox”, and “sandboxed commands run without network access by default”, with only approved domains added to the outbound allowlist [6]. The point is not which vendor is right. It is that “sandbox” names a different boundary in each product, and the only way to know yours is to open the page.
Approvals and sandboxes are different controls
The permission prompt and the sandbox feel like one feature because you meet them together. They are not, and the difference decides which one you can afford to switch off. OpenAI’s documentation puts it in two lines: “The sandbox defines technical boundaries. The approval policy decides when the agent must stop and ask before crossing them” [4].
Enforcement is what separates them. A permission decision is made before a command runs, from the text of the command. The sandbox is enforced by the operating system on the running process, so it holds “regardless of what the model chose to run” [1]. macOS uses the built-in Seatbelt framework; Linux and WSL2 need bubblewrap and socat installed from your package manager; native Windows is not supported by Claude Code’s sandbox, so run it inside WSL2 there [1]. Codex uses a native Windows sandbox in PowerShell and the Linux implementation under WSL2 [4].
The knobs are named differently and mean nearly the same things. Codex documents three common sandbox modes, read-only, workspace-write and danger-full-access, crossed with three common approval policies, untrusted, on-request and never [4]. Claude Code offers permission modes instead: Manual, which appears in settings under its config value default, plus acceptEdits, plan, auto, dontAsk and bypassPermissions [2]. A few refusals survive every setting. In Claude Code, an rm or rmdir aimed at a critical path such as rm -rf / or rm -rf ~ is never approved by an allow rule or a hook in any mode, which the documentation describes as a circuit breaker that “guards against model error” [2].
One default is worth copying whatever you run. On launch, Codex detects whether the folder is version-controlled and recommends workspace-write with on-request approvals if it is, and read-only if it is not [5]. That is a vendor encoding the oldest rule in this business: an agent working in a git repository is recoverable, and an agent working in your Downloads folder is not.
The approval tax is what pushes people into bypass mode
Nobody disables safety on day one. They disable it in week three, after the hundredth prompt asking whether npm test may run. The vendors know this. Both sandbox designs exist explicitly to cut that number: Codex says “the sandbox reduces approval fatigue” [4], and Claude Code’s sandbox “lets Claude run most shell commands without stopping to ask permission” by moving the decision from each command to a boundary you set once [1].
It is worth measuring your own number before deciding it is intolerable.
sessions × prompts × seconds ÷ 60. Counts the interruption, not the recovery time afterwards. Computed in the page; nothing is sent anywhere.
Whatever that number is, the fix is to widen the boundary, not to delete it. These tools let you name the extra directories a command may write and the domains it may reach, through sandbox.filesystem.allowWrite and network.allowedDomains in Claude Code [1], and through writable roots [4] and domain rules [5] in Codex. Those changes are specific, they are written down, and they survive a session.
The other option is the one with the warning label on it. Claude Code’s bypassPermissions mode “disables permission prompts and safety checks so tool calls execute immediately”, and Anthropic’s guidance is to “only use this mode in isolated environments like containers, VMs, or dev containers without internet access, where Claude Code cannot damage your host system” [2]. The stronger sentence sits a paragraph below: “bypassPermissions offers no protection against prompt injection or unintended actions” [2]. Codex’s equivalent, danger-full-access with approval_policy = "never", “removes the filesystem and network boundaries” [4]. These modes are for a machine you would be willing to reset, and they are a reasonable choice on such a machine. On your daily laptop, with your keys on it, they are not a shortcut, they are a different risk posture entirely.
Assume the agent will read something hostile
The reason a bounded agent matters more than a careful one is that the instructions it follows do not all come from you. Text in a file, a web page, an issue comment or a dependency’s README arrives in the same context window as your request, and OWASP ranks prompt injection as the first item in its Top 10 for LLM Applications, LLM01:2025 [7]. On whether you can engineer the problem away, OWASP is direct: “Given the stochastic influence at the heart of the way models work, it is unclear if there are fool-proof methods of prevention for prompt injection” [7]. OpenAI repeats the warning where it bites hardest, telling you to use caution when enabling network access or web search because “prompt injection can cause the agent to fetch and follow untrusted instructions” [5].
Defences exist and they are worth having. Claude Code’s auto mode runs a separate classifier model over actions before they execute, blocking anything that escalates “beyond your request”, targets “unrecognized infrastructure”, or “appears driven by hostile content Claude read”; tool results are stripped before the classifier sees them, “so hostile content in a file or web page can’t manipulate it directly” [2]. Codex can route eligible approval requests to a reviewer agent instead of to you with approvals_reviewer = "auto_review" [4]. Both are real improvements and neither is a guarantee; Anthropic’s own note on auto mode says it “reduces permission prompts but does not guarantee safety” [2].
Which brings the argument back to the network boundary, because that is where a successful injection turns into a loss. Anthropic warns that “allowing broad domains such as github.com can create paths for data exfiltration”, since the proxy makes its allow decision from the client-supplied hostname without inspecting TLS, leaving room for domain fronting [1]. The practical rule is small and unglamorous: any session where the agent reads material you did not write is a session that gets a short allowlist.
A setup that survives a bad session
Start in git and commit before you start, so that the worst local outcome is git checkout . rather than an evening of reconstruction. Give each job its own directory and resist widening it; every --add-dir is a permanent enlargement of the blast radius for a temporary convenience.
Deal with credentials explicitly, because the defaults do not. Claude Code’s sandbox read policy still reaches ~/.ssh and ~/.aws, and sandboxed commands “inherit the parent process environment by default, including any credentials set there” [1]. The sandbox.credentials setting exists to deny those file reads and unset those variables, and Anthropic’s own recommended baseline is to add entries for credential directories such as ~/.aws and ~/.ssh precisely because the default read policy allows them [1].
Make the sandbox fail closed. By default, if it cannot start because dependencies are missing or the platform is unsupported, Claude Code “shows a warning and runs commands without sandboxing” [1]. On Linux and WSL2 those dependencies are bubblewrap and socat for Claude Code [1], and bubblewrap for Codex [4]. Setting sandbox.failIfUnavailable to true turns a warning you will scroll past into a hard failure [1].
For anything unattended, move up a level of isolation rather than down a level of caution. Anthropic’s comparison of environments is a useful ladder: the sandboxed Bash tool isolates Bash commands and their child processes, a dev container or custom container isolates a full development environment and needs Docker, and a virtual machine isolates a whole operating system [3]. On Linux and macOS, Claude Code refuses to start in bypass mode when running as root or under sudo, which is a hint about the intended shape of an autonomous setup [2]. Know your escape hatches too, since each of these tools has one: Claude Code can retry a blocked command outside the sandbox with a dangerouslyDisableSandbox parameter unless you set allowUnsandboxedCommands to false [1], Codex has rules that allow, prompt or forbid command prefixes outside the sandbox [4], and Antigravity CLI records the same thing as an unsandboxed(...) allow rule [6].
What still goes wrong
The sandbox is narrower than the agent. Claude Code’s built-in sandbox restricts Bash commands and their child processes, while “built-in file tools, MCP servers, and hooks still run directly on your host” unless you wrap the whole process in a container, a VM or the standalone sandbox runtime [3]. So the boundary you configured on Monday may not be the boundary that applies when the agent calls a tool rather than a shell command, and MCP servers you installed for convenience are inside your trust boundary whether or not you audited them.
The network boundary is a hostname allowlist, not a content filter. By default the built-in proxy “does not terminate or inspect TLS on outbound traffic”, so what leaves through an allowed domain is not examined, and broad entries can be used to reach hosts you did not intend [1]. Treat an allowlist as a way to reduce the number of places data could go, not as proof that nothing went anywhere.
And the underlying problem is not solved. Prompt injection sits at the top of the OWASP list with no fool-proof prevention [7], the classifier layers reduce risk without guaranteeing safety [2], and a local model buys confidentiality at a capability cost you have to measure yourself [8]. The realistic posture is not confidence, it is containment: assume that once a month something will happen in a session that you did not ask for, and set up so that when it does, you lose an hour rather than a client’s data. If you are not willing to run that session, run it in a virtual machine, or do not run it.
- 01Anthropic — Claude Code: Configure the sandboxed Bash toolcode.claude.com
- 02Anthropic — Claude Code: Choose a permission modecode.claude.com
- 03Anthropic — Claude Code: Choose a sandbox environmentcode.claude.com
- 04OpenAI — Codex: Sandboxlearn.chatgpt.com
- 05OpenAI — Codex: Agent approvals & securitylearn.chatgpt.com
- 06Google — Antigravity CLI: Sandboxantigravity.google
- 07OWASP — LLM01:2025 Prompt Injectiongenai.owasp.org
- 08Ollama — gpt-oss model libraryollama.com