A coding agent does not need malicious intent to cause a serious incident. A mistaken path, stale assumption or overly broad cleanup command can remove a repository, rewrite Git history, truncate a database or destroy cloud resources in seconds.

The obvious response is to ask the user before every command. That works for a while. Then normal development produces dozens of prompts, the user enables broad approval and the supposed safety boundary disappears.

A better design keeps normal work fast while placing a narrow deterministic veto around operations that are clearly catastrophic.

What destructive agent operations look like

Real incidents rarely arrive as a command labelled “destroy everything.” They appear inside routine tasks:

  • “Clean generated files” resolves the wrong directory then recursively deletes the workspace.
  • “Return to a clean branch” runs a hard reset and destructive clean before uncommitted work is saved.
  • “Reset the test database” points at a production connection string inherited from the shell.
  • “Free disk space” removes Docker volumes that contain local databases.
  • “Recreate the namespace” deletes a Kubernetes namespace shared by another service.
  • “Fix the deployment” applies a Terraform destroy plan against the wrong workspace.
  • “Update the branch” force pushes over commits that only existed on the remote.

Each action can be valid in the right context. The danger comes from target, scope and reversibility.

Why broad permission prompts fail

Provider permission systems answer an important question: may the agent use a tool? The user might allow the shell because tests, builds and package management all depend on it. That approval is too broad to answer whether a specific database deletion or filesystem operation is safe.

Authority

May this agent invoke the shell during the current session?

Policy

May this exact operation affect this target with this scope?

Keep the authority prompt. Add deterministic policy closer to the operation.

Use target, scope and reversibility

A useful command guard does more than match scary words. It evaluates the shape of the action.

SignalQuestionExample
TargetWhat resource will change?Repository path, production database, cloud account
ScopeHow much can the action affect?One file, every table, all namespaces
ReversibilityCan the result be recovered reliably?Move to trash versus permanent recursive deletion
ContextDoes the environment raise the stakes?Development workspace versus production
Intent mismatchDoes the action exceed the stated task?Formatting code followed by a force push

Deterministic rules are best for high-confidence cases. They should not attempt to infer every nuance of operator intent. Ambiguous actions can be warned or escalated for review. Known catastrophes can be blocked.

Protect the operations developers recognise

Files and permissions

Watch for recursive deletion aimed at broad or protected paths, destructive disk operations and permission changes that make protected directories writable. Resolve paths before evaluating scope. A relative path can become dangerous after a working-directory change.

Git history

Guard hard resets, destructive clean operations, branch deletion and force pushes. The important signal is not that Git is being used. It is that work or shared history may become unreachable.

Databases

Distinguish narrow mutations from schema drops, truncation and broad updates or deletes. Include target environment in the decision. The same reset command may be routine against an ephemeral test database and unacceptable against production.

Containers and Kubernetes

Look for system-wide prune, volume deletion, namespace removal and broad resource deletion. Developers often treat containers as disposable while stateful volumes and shared clusters are not.

Cloud and infrastructure as code

Protect resource deletion, stack teardown and Terraform destroy operations. Local interception helps when the action goes through a guarded shell. Remote policy and cloud IAM must carry the boundary when an API, hosted agent or native integration performs it elsewhere.

Credentials and exfiltration

Track sensitive sources and observable destinations without copying secrets into logs. Reading an environment variable may be legitimate. Collecting multiple credential stores then sending content to a network destination deserves a different decision.

The interception point is the product boundary

A guard cannot block an action it never sees. This limitation should be visible in the product and in every security claim.

  • A Claude Code or terminal hook can evaluate commands invoked through that supported hook.
  • An editor adapter may observe writes but not native API calls from a separate process.
  • A local daemon can inspect local events but not a hosted agent running in another environment.
  • An MCP gateway can govern traffic routed through it but not direct credentials used around it.
  • Cloud IAM and database permissions remain the final boundary for remote systems.

This is why “configured” is not sufficient. A security UI should state whether a mechanism is supported, installed, active and recently proven on the host.

What should happen when a guard fires

The response needs to be immediate and understandable. A good event tells the user:

  • Which agent or tool initiated the action
  • Which protected surface was involved
  • Why the operation matched policy
  • Whether it was blocked, warned or allowed
  • What the user can do safely next

Use a visible desktop or editor alert for serious events. Sound can help when the agent is working in the background, but it should be reserved for high-severity decisions and remain configurable. Constant noise trains users to ignore the product.

Do not put secrets or full sensitive commands into notification text. Preserve sanitized evidence, fingerprints and reason codes for later review.

A safe test plan

  1. Create an isolated temporary workspace with no valuable data.
  2. Install the guard on one supported agent path.
  3. Run harmless commands and confirm they do not trigger.
  4. Use a canary action that resembles a protected operation but cannot affect real resources.
  5. Confirm the operation is blocked before execution.
  6. Confirm the user receives a clear notification and sanitized event record.
  7. Restart the agent then verify the guard remains active.
  8. Test a deliberately unsupported path and make sure the UI does not claim protection.

The last step matters. Honest limits are part of the control. A user who knows a remote path is outside coverage can add an infrastructure boundary. A user shown a false green state cannot.

The operating model

Let provider sandboxes constrain general authority. Let developers approve legitimate work. Let a narrow command guard veto known catastrophic actions on supported paths. Let downstream IAM and service policy protect remote systems.

That combination preserves autonomy without gambling the repository, database or production environment on one prompt.

Sources and further reading

VS Code: Agent approvals documents approval modes and the consequences of bypassing them.

VS Code: Security for AI agents explains terminal authority, auto-approval risk and workspace trust.

OpenAI: Running Codex safely describes the role of filesystem and network sandboxing.

OWASP Secure Coding with AI Cheat Sheet provides broader guidance for agents that run commands and install software.