How to secure an AI coding agent without relying on the system prompt

“Don’t delete prod” in a system prompt is not a security control. The real boundary is where the model physically cannot act: API surface, isolation, operation filter, audit. Working reference: enterprise-code-bastion.

How to secure an AI coding agent without relying on the system prompt

A prompt is a wish. A perimeter is when the model physically cannot reach files or a shell: native tools off, an MCP intermediary, Docker per project+task, a filter before execution, an audit trail. Below is a working reference — and where the design gives way.

You can’t write “don’t delete prod” in a system prompt and call it a security control.

The model will read it. It will even understand it. Then the context will make rm look reasonable, and it will run it. Not because it is malicious. Prompt text is not a rule the model must obey the way a firewall must drop a packet.

Agent security sits in the layer the model cannot walk around: API surface, tokens, isolation, the operation filter. While everything works, that looks a lot like “we wrote a good system prompt.” The difference shows up once. Usually expensive.

Why “we wrote a good system prompt” fails a security review

Fintech, government, and large IT keep agents off their codebases: one bad command’s blast radius is the repo, the secrets, the infrastructure. “Trust us, we wrote a good system prompt” lands as a wish-list in front of a bank’s security team. It does not become a control plane.

Enterprise already asks vendors for least privilege, isolation, full audit, reproducibility. We still let AI agents in without that package — “the model is smart.” Intelligence does not shrink the attack surface. It changes the failure shape: instead of a crashing script, a confident rm in the middle of a “reasonable” plan.

A working bastion

I built a working reference for that perimeter — enterprise-code-bastion: a session launcher, an MCP server with secureBash, a session registry. Constrain the agent with architecture — native tools stripped, every action through a filtering intermediary in a sandbox.

In practice:

  1. Unit of work = project + task. Each pair gets its own Docker container with only that project mounted. Other sessions stay blind to it.
  2. Claude with native tools off. --tools "" — no stock Read, Write, or Bash. Alone, the agent does not touch the host.
  3. One channel out: MCP (Model Context Protocol) over HTTP. It needs a file or a shell command — it asks the server. It cannot act alone.
  4. Filter before execution. In production, deterministic logic and/or a separate LLM filter screens each command before docker exec. Destructive work dies before it runs.
  5. Execute only inside the session container. Approved commands go through docker exec in the sandbox, not on the host. The result comes back to the model.
  6. Audit. MCP requests land in logs/mcp.log (JSON Lines); sessions in sessions.csv. For compliance that is an entry condition, not a nice-to-have.

In the demo repo everything sits on one machine so the scheme is easy to see: project files and the MCP server side by side. In production you split them — code on one host, MCP guard on another. Then even if Claude somehow got Bash or Read back, there is still no path to the project files: they are physically elsewhere. The simplification in the repo is intentional.

Full methodology, control table, launch commands: Enterprise code bastion howto.

Where it breaks

  • Gate is only an LLM. The filter has its own prompt-injection surface. A hard guarantee needs a deterministic allowlist next to the model — otherwise you just moved trust from one model to another.
  • secureBash still runs commands inside the container. Isolation is only as strong as the sandbox hardening: non-privileged, controlled egress, resource limits. A compromised container is still a blast radius: the host outside may survive, but everything that ran in the sandbox is already exposed.
  • A flat sessions.csv. Fine as an append-only demo journal. At org scale you need a real session store, RBAC, and an approval workflow.

From this reference you can see the boundary: useful on one side, physically unable to step outside on the other — and what still needs building when security says pilot ok, now production.

Who this is for

CISOs, CTOs, Heads of AI, architects who need Claude (or an equivalent) on the code and still need to pass a security review. Not a weekend tutorial on starting an agent. The model reasons and proposes a plan; it cannot leave the allowed box — no direct tools, no direct access to the project tree, every command screened and run in a sandbox.

Another control is splitting task definition from execution (observable shared state, git as audit): How to control what AI agents do. The bastion covers the access perimeter; the split covers work transparency. You usually need both.

Write the system prompt anyway — the agent reasons better with it. But when the model decides rm looks reasonable, what remains is whatever you built into the architecture. If that layer is empty, the prompt will not save anyone. Repo: github.com/dobryakov/enterprise-code-bastion

Howto: dobryakov.net/howto/enterprise-code-bastion.html

Related: book-as-context for subject-matter grounding, and skill onboarding when the assistant accumulates behavior packs.