How to Harden Your Agent Runtime to Fail Closed
Fail-open agent runtimes execute whatever they are handed. Here are the hardening layers that make an agent runtime fail closed by default.
An agent runtime handles the unexpected in one of two ways. Fail-open runs the action and logs it. Fail-closed blocks it until something approves. A shell command you never anticipated, a call to a host you never listed: fail-open executes it, fail-closed stops it cold. That default decides how much damage a confused agent can do.
Why most setups default to fail-open
Most runtimes ship fail-open because it is the path of least resistance while you build. Every block is an interruption when you are trying to get the agent working, so you widen permissions until the work flows: let it run the command, hit the API, read the file. That posture then rides straight into production, because nobody revisits it once the demo passes. The mechanism is allow-by-default with a denylist bolted on afterward, and the consequence follows directly: every capability you forgot to deny is one the agent keeps, and a single injected instruction executes with the reach you have yourself.
Five hardening layers
Egress credential firewall
An agent holds real secrets to do its job: model keys, tracker tokens, a database URL. Fail-open egress lets the runtime reach any host, so an exfiltration route is one crafted instruction away. A prompt-injected page can tell the agent to POST your environment to an endpoint it chooses, and nothing on the wire says no. The fail-closed version is a default-deny egress allowlist: the runtime reaches the hosts the task needs and nothing else, secrets resolve as scoped references at call time rather than ambient variables, and every request is logged. The question stops being whether you caught the exfiltration; the route does not exist. More on this in Securing Your Agent Runtime.
Dangerous-command denylist hardening
A denylist that blocks rm -rf and stops there is theatre. A shell offers many ways to phrase the same destructive act: variable expansion, a base64 string decoded and piped to sh, command substitution, chained operators, a symlink that redirects a benign-looking path. Any denylist kept as a list of forbidden strings loses to the first shell-escape bypass class it never enumerated, and you cannot enumerate them all. Hardening a dangerous-command denylist means evaluating resolved intent rather than surface syntax: parse the command, resolve what it will actually execute, and judge that. Stronger still, invert the model: allow the commands the job needs, deny the rest by default, and an unknown bypass fails closed instead of sliding through.
IDOR protection on agent-accessible resources
An agent that fetches records by identifier will eventually be handed the wrong one. Insecure direct object reference is the old web bug, and it bites harder with agents because the agent composes the identifiers itself from the context it holds. If a resource check confirms only that a record exists, not that this agent, this tenant, this task may read it, a confused lookup crosses a customer boundary. Fail-closed means every agent-accessible resource enforces ownership at the point of access, not in the interface: authorize against the object, scope every query to the caller, and deny whenever ownership is ambiguous. Existence is never authorization.
Fail-closed gateway defaults
The gateway is where the agent's intended action meets your policy. Tool calls, API requests, and shell execs all pass through it, and its answer to an action it does not recognize is the whole game. A fail-open gateway returns allow when a rule is missing, a policy is malformed, or evaluation throws, which means a bug in your policy engine silently grants access. A fail-closed gateway returns deny under every one of those conditions. Missing rule: deny. Policy errors: deny. The policy service times out: deny. The operator adds explicit allows for known-good actions, and the absence of a decision is read as no. Safety becomes the state you land in when something breaks, not one you hoped you configured.
Path-traversal guards
Give an agent file access and it will construct a path from untrusted input sooner or later. With no guard, a ../../ sequence walks out of the workspace into credentials, config, or another task's data. The naive fix of stripping .. loses to encoding tricks, absolute paths, and symlinks that resolve outside the boundary after the check passes. A fail-closed guard resolves the path to its canonical form first, confirms it sits inside the allowed root, and denies otherwise. The boundary is enforced on the resolved path, so a traversal attempt meets a wall instead of a file it was never meant to touch.
What a fail-closed posture looks like in practice
Put the five together and the end state is an agent that does exactly what its task requires and nothing past it. It reaches the hosts the job needs, runs the commands the job needs, reads and writes inside its own workspace, and touches only the records it owns. Every boundary answers an unexpected request the same way: no, unless something explicitly said yes. It stays capable inside a fence, and the fence holds when the agent is confused, misdirected, or carrying an instruction someone slipped into its context. That is the line between a demo you show and a runtime you hand a client.
Where this fits Paperclip
Paperclip runs each agent through an adapter on infrastructure you control, and by design the local runtime is unsandboxed; its own docs put the security posture on the operator, not the platform. That's the honest division of labour: the platform gives you the control plane, and the fail-closed fence around it is yours to set. A platform can't enforce a posture it doesn't ship, which is exactly why owning your runtime matters, and why operators taking agents to production treat these five layers as their own responsibility, not a feature they can assume is already on.
The takeaway
Fail-closed is not a control you add at the end. It is the default you start from and open deliberately, one allow at a time. If you are standing up the surrounding environment, the same discipline runs through the whole build in How to Set Up an AI Agent Company.
Subscribe below for more on running AI-native operations. Practical field notes on agents in production, straight to your inbox.

