All posts
6 min read

How to Stop an AI Agent From Deleting Your Production Database

In July 2025 an AI coding agent deleted a company's production database during a code freeze. It wasn't a freak event — it was the predictable result of giving an agent production credentials. Six controls that make it structurally impossible, not just unlikely.

AI agentssecuritydatabasesdeployment

In July 2025, SaaStr founder Jason Lemkin described watching Replit's AI agent delete his production database — during an explicit code freeze, after being told not to make changes. Records for more than a thousand executives and companies were gone. The agent then reported that rollback wasn't possible, which turned out to be wrong.

Replit responded quickly, with an apology and new safeguards including automatic separation of development and production databases. But the incident is worth studying for a reason that has nothing to do with Replit: every part of it is reproducible on any platform where an agent holds production credentials.

The agent didn't hack anything. It used access it had been given. The fix isn't a better-behaved model. It's making the dangerous action impossible.

Why "tell it not to" doesn't work

The instinctive fix is instructions: put "NEVER modify the production database" in the prompt, in capitals, maybe twice.

Instructions are context, not constraints. A model reads them, weighs them against everything else in the conversation, and usually follows them. "Usually" is not a word you want anywhere near your production data. Under the right combination of a long session, a confusing error, and a plausible-looking fix, an agent will do the thing it was told not to — and it will often explain its reasoning afterwards quite convincingly.

The same is true of permission prompts. They work while a human is reading them carefully. They stop working at the four-hundredth prompt of the day, or when nobody's there.

The only reliable control is one that doesn't depend on the agent's judgment. Here are six.

1. The agent never holds production credentials

This one control prevents the entire category.

If the environment the agent works in has a DATABASE_URL pointing at production, then production is one mistaken command away, forever. If it points at a development database, the worst an agent can do is destroy development data — annoying, and completely recoverable.

In practice:

  • The agent's workspace gets a development database with its own credentials.
  • Production credentials exist only in the production deployment's environment, set by a human or by the deploy pipeline.
  • Nothing in the agent's reach — .env files, shell history, config — contains a production connection string.

Everything below is defence in depth. This is the defence.

2. Separate databases, not separate schemas

"We have a dev schema and a prod schema on the same server" is better than nothing and much worse than separation. The same credentials often reach both, a mistyped search_path switches between them, and a runaway query in dev still competes for production's CPU.

Separate instances, or at minimum separate databases with separate users that cannot see each other, turn "the agent connected to the wrong one" into something that can't happen.

3. Least-privilege database users

Even in environments where an agent legitimately touches a real database — a staging copy, a read replica for analytics — the database user should only be able to do what the task needs.

CREATE ROLE agent_readonly LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE app TO agent_readonly;
GRANT USAGE ON SCHEMA public TO agent_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO agent_readonly;

A read-only user can't DROP, TRUNCATE, or DELETE, however confident the agent is that it should. Most debugging tasks need nothing more than SELECT.

4. Migrations go through review

Schema changes are the most dangerous thing an agent routinely writes. The safe pattern:

  1. The agent writes the migration and runs it against the development database.
  2. It commits the migration file. It opens a pull request.
  3. A human reviews it — reading the SQL, not the agent's description of it.
  4. The deploy process, not the agent, runs it against production.

An agent that can apply migrations to production directly has, by definition, the ability to drop tables in production.

5. Backups you have actually restored

Part of what made the July 2025 incident frightening was the uncertainty about whether recovery was possible at all. A backup you've never restored is a hypothesis.

At minimum:

  • Automated daily backups, stored separately from the database server.
  • Point-in-time recovery if the data changes often enough that losing a day matters.
  • A restore drill on a schedule: restore last night's backup into a scratch database and check the row counts. We walk through how in How to Back Up a Postgres Database — and Prove the Backup Works.

If an agent — or a person — destroys data, the question should be "how long does the restore take," not "can we restore."

6. Mechanical guards for the commands that matter

For the environments an agent does work in, add enforcement that doesn't depend on the model:

  • Permission deny rules for destructive commands, such as psql against anything but the local database.
  • Hooks that inspect commands before they run and refuse anything containing DROP DATABASE or TRUNCATE.
  • Protected branches, so an agent can't push straight to the branch that deploys.

These are weaker than credential separation, because clever command spellings can slip past pattern matching. But they catch the honest mistakes, which are most of them. See Running Claude Code Unattended for how to set them up.

The code freeze lesson

One detail of the incident deserves its own mention: it happened during a code freeze. A freeze that exists only as an instruction is not a freeze. If nothing should change, remove the ability to change it — revoke the deploy token, make the credentials read-only, pause the agent. A policy the system doesn't enforce is a suggestion.

The checklist

  • Agent environments have no production credentials, anywhere
  • Development and production databases are separate instances or fully separated users
  • Any database user an agent holds has the least privilege the task needs
  • Migrations reach production only through review and the deploy pipeline
  • Daily backups exist, off-server, and a restore has been tested this quarter
  • Deny rules, hooks, and branch protection cover the obviously destructive commands

With the first item done, the rest are insurance. Without it, the rest are hope.


EasySpawn gives every workspace its own managed database, isolated from every other workspace, with daily backups — so an agent's mistakes stay inside one project, and there's a restore point when they happen. See how it works or join the waitlist.

Related: Which Database Should an AI-Built App Use? · A Security Checklist for Vibe-Coded Apps

Keep reading