AI Agent Filesystem Safety: Prevent Destructive Writes and Path Escapes
One bad path can turn a helpful coding agent into a data-loss incident. Build filesystem boundaries that remain safe even when the model is wrong.
An AI agent does not need malicious intent to delete the wrong directory. It only needs a vague instruction, an unresolved environment variable, a symlink, or a path check performed before normalization. AI agent filesystem safety must assume the model will eventually produce a dangerous target.
The secure design makes that target impossible to reach, then adds previews and recovery for everything that remains.
Define a Capability Root
Give each task a dedicated workspace such as /srv/jobs/7f3a/work. The agent receives a capability for that directory, not general access to the host filesystem. Mount project input read-only where possible and place outputs on a separate writable volume.
Do not rely on a system prompt saying “stay in the project.” The enforcement must live in the executor.
import path from "node:path";
function resolveInside(root, requested) {
const base = path.resolve(root);
const target = path.resolve(base, requested);
if (target !== base && !target.startsWith(base + path.sep)) {
throw new Error("path escapes task root");
}
return target;
}
Expected result: ../../etc/passwd and absolute outside paths are rejected before any file operation.
Defend Against Symlinks and Races
String-prefix checks are not enough. A path inside the workspace can be a symlink to somewhere outside it. Resolve the real parent path, reject unexpected symlinks, and use operating-system primitives that avoid following links where available.
There is also a time-of-check/time-of-use problem: a file can change between validation and opening. For sensitive executors, operate through directory file descriptors, open with no-follow flags, and perform work in an isolated container or sandbox whose mount table is the real boundary.
Expected result: replacing a safe directory with a symlink cannot redirect a write into the host.
Separate Read, Create, Modify, and Delete
Filesystem access is not one permission. Reading a repository is lower risk than overwriting configuration; creating a new file is lower risk than deleting a tree.
Model operations as explicit tools:
read_file(path)
create_file(path, content)
apply_patch(path, diff)
move_to_trash(path)
request_permanent_delete(path)
Require approval for overwrites outside generated-output folders and for bulk changes over a threshold. Prefer patches so reviewers can see intent. Use trash or snapshots instead of permanent deletion.
Expected result: the model cannot smuggle rm -rf through a general shell tool when a narrower file tool would suffice.
Make Plans Concrete Before Execution
Expand globs and variables, normalize every target, and display the exact resolved list before a destructive or broad write. Reject empty variables, root directories, home directories, and targets above the capability root.
Add budgets: maximum files, maximum bytes, maximum directory depth, and maximum percentage of a repository changed in one action. Budgets turn an unexpected loop into a stopped task instead of a wiped workspace.
Verify and Recover
Hash important inputs, capture a pre-change snapshot, and log tool name, resolved target, result, and task identity. After writes, verify the expected files exist and that unrelated files did not change. Keep secrets out of logs.
Test path traversal, absolute paths, Unicode oddities, symlink chains, case-insensitive filesystems, empty variables, glob explosions, and concurrent path replacement. A safety boundary that only survives normal paths is decoration.
The Takeaway
Safe filesystem agents use hard capability roots, real-path and symlink defenses, narrow operations, explicit resolved targets, change budgets, and recoverable deletion. The model can still make a bad decision. Your executor’s job is to keep that decision small, visible, and reversible.
> Want more like this?
Get the best AI insights delivered weekly.
By subscribing, you agree to our Privacy Policy. You can unsubscribe at any time.
> Related Articles
AI Agent State Snapshots: Resume Long Jobs Without Repeating Side Effects
Durable agents need more than chat history. Snapshot plans, tool results, permissions, and idempotency state so a crash can resume safely instead of replaying the world.
Embedding Model Migration: Change Vectors Without Breaking Search
Embedding upgrades change the geometry of your index. Use versioned vectors, dual writes, shadow queries, and measured cutover instead of mixing incompatible representations.
LLM Request Coalescing: Stop Paying Twice for the Same Answer
When identical LLM requests arrive together, single-flight execution can collapse them into one upstream call—if cache keys, streaming, failures, and tenant boundaries are designed correctly.
Tags
> Stay in the loop
Weekly AI tools & insights.