Shotoku
← Blog

How to stop an AI agent from deleting your production database

· By the Shotoku team

Short answer:make sure the agent can’t reach production credentials, use tokens scoped to the job, keep backups outside the system they protect, and gate destructive tools so a human decides. No single step is enough. A prompt that says “never delete anything” isn’t one of those steps at all.

How have agents deleted production data?

Two public incidents in 2026 show how it happens:

In both cases the agent could do far more than its task needed, and the backups could be destroyed by the same action.

What actually prevents it?

SafeguardWhat it stopsWould it have helped?
Keep production credentials away from the agentUsing a token it wasn't meant to havePocketOS: yes
Scope tokens to one environment and taskA staging job touching productionPocketOS: yes
Keep backups outside the systemLosing the backups in the same actionBoth: yes
Keep production infrastructure commands away from the agentDestructive plans running unreviewedDataTalks.Club: yes
Gate destructive tools with a policyTool calls the agent makes through MCPOnly for actions that pass through the gate
Rules in the promptNothing reliablyPocketOS had these

Would Shotoku have stopped these incidents?

Probably not on its own. Shotoku checks calls that pass through it. Based on the reports, the PocketOS agent used a token it found and called an API directly, and that route never touches an MCP gate. The same goes for a shell command. Fix credentials and backups first.

Where a gate helps is the agent’s normal, sanctioned route. If your agent reaches data through MCP tools and has no other route, a policy decides what those tools may do. An HTTP gatewayfor traffic outside MCP is in the repo as an alpha, but it isn’t on npm.

How do you gate destructive tools?

Wrap your MCP server with Shotoku, then write a policy. Reads run, drops are refused, and everything else waits for a person:

policy.yaml
rules:
  - resource: postgres__query
    verdict: approved
  - resource: postgres__list_*
    verdict: approved
  - resource: postgres__drop_*
    verdict: denied

defaultVerdict: pending_approval

We tested this policy on the current npm release, with a stand-in server that reports when a tool really runs:

Tool callResultReached the server?
postgres__queryapprovedYes
postgres__drop_tabledenied, finalNo
postgres__delete_rowspending_approvalNo, until a human approves that exact call
Check what your read tool can run. If a query tool accepts any SQL, approving it also approves DROP TABLE sent through it, because the policy matches on the tool name. Connect it with a read-only database user.

A checklist before you give an agent access

  1. Search the agent’s workspace for tokens, .env files and cloud credentials it doesn’t need.
  2. Give it a database user with only the rights the task needs.
  3. Test a restore from a backup stored in a separate account.
  4. Turn on deletion protection where your provider offers it.
  5. List every route the agent has: MCP tools, shell, HTTP and CI.
  6. Put a gate on the routes you keep, and hold unknown actions by default.

Common questions

Is this only a problem for coding agents?

No. Any agent with credentials and a loose task has the same risk. Coding agents are simply the most common place for it, because they have shells and tokens close at hand.

Do approval prompts solve it?

Only if the person reads them and the agent has no other route. A prompt on every action teaches people to click yes, so reserve them for actions that are hard to undo.

Shotoku is built for spend controls, and the same policy engine covers tool calls like these. Start with the MCP guide.

Related