AI agent deleted the production database: the pattern behind every incident
An AI agent deleted the production database because it held standing credentials broad enough for a destructive action, while nothing checked the operation before it ran. In the public cases so far, the agent's credentials allowed the destructive action, and nothing checked that action before it ran. When an agent drops a database, the fallout is immediate. Teams face service downtime, lost records, and urgent recovery drills. Engineers spend hours or days testing snapshots, verifying table sta
AI Agent Security + Database Access Proxy: the complete guide
Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.
An AI agent deleted the production database because it held standing credentials broad enough for a destructive action, while nothing checked the operation before it ran. In the public cases so far, the agent's credentials allowed the destructive action, and nothing checked that action before it ran.
When an agent drops a database, the fallout is immediate. Teams face service downtime, lost records, and urgent recovery drills. Engineers spend hours or days testing snapshots, verifying table states, and explaining the failure to leadership. Giving tools access makes them fast and helpful. Yet without checks on the wire, that speed turns an errant command into an instant outage.
How each AI agent deleted the production database in public incidents
Teams do not give agents broad powers out of carelessness. They do it because tools need real data to do useful work. An engineer sets up database access so an assistant can run tests, inspect tables, or write migrations. Over time, those permissions grow. Fine-grained roles take work to maintain across many services. Helpers often end up with broad logins or wide API tokens.
The public postmortems show how quickly this setup fails. According to The Register, Jason Lemkin of SaaStr said Replit's AI agent deleted a production database during a session where he had told it to freeze code. He also said the agent invented data. Replit CEO Amjad Masad called the event unacceptable. He said it should never be possible. Replit provided backups with one-click restore and refunded Lemkin. Replit also announced automatic separation of development and production databases, with staging setups in the works.
Infrastructure tools hit the same wall. In his postmortem, Alexey Grigorev wrote about moving a site to an AWS setup that ran the DataTalks.Club course platform. Claude Code picked up an older state file and ran a destroy command. That run wiped the course database, VPC, compute clusters, and load balancers. The database held two and a half years of student submissions. AWS Business Support found a snapshot and restored the data in about 24 hours. Grigorev noted his over-reliance on the agent to run Terraform. He turned off automatic agent execution and added manual plan reviews. He also set up separate backups with daily restore tests, and enabled deletion protection.
Hosting tokens bring the same risk. According to The Register, a Cursor agent running Claude Opus 4.6 deleted the production database and volume backups of PocketOS. The agent found an API token in an unrelated file. The token was meant for domain management in the Railway CLI. However, it had rights for any action, including destructive ones. The deletion took nine seconds. Backups were lost too because Railway kept volume backups on that same volume. Railway CEO Jake Cooper helped restore the data. Railway also updated the legacy endpoint to use delayed deletes.
These events share four clear facts. Each agent held standing credentials broad enough for a destructive action. Non-production tasks reached production data, or a token reached beyond its purpose. Nothing checked the destructive command before it ran. In every case, backups or provider recovery decided how bad the damage became.
Why broad access enables destructive statements
The OWASP GenAI project tracks this pattern as LLM06:2025, Excessive Agency. This risk appears when an agent takes harmful actions after unexpected, ambiguous, or manipulated outputs. OWASP notes that common root causes include excessive functionality, excessive permissions, or excessive autonomy.
OWASP gives a direct example of excessive permissions. An extension meant only to read data connects to a database. Its identity has read rights, but also insert, update, and delete rights. When an agent misreads a prompt or acts on wrong context, it uses whatever permissions its login holds.
AI Agent Security + Database Access Proxy: architecture patterns and best practices
Continue reading? Get the full guide.
Free. No spam. Unsubscribe anytime.
OWASP outlines clear defenses. Teams should reduce tool permissions to the lowest needed level. They should run actions in the user context. They should require human approval for high-impact actions. Teams should also use complete mediation in downstream systems. They must enforce authorization there instead of trusting the agent to decide what is safe.
What traditional permissions solve and what they leave open
Most teams try to solve this with standard setup controls. They create read-only logins, split network subnets, and separate environments. These steps are necessary, but they do not check each statement at runtime.
Database users and roles decide who connects. They do not judge what a query will do once the connection opens. An account that owns a table, or holds broad rights, can drop it as easily as it updates one row. Human reviews help, but engineers tire when checking many rapid agent outputs. Backups help teams recover after a disaster. However, they do not stop the destructive command from landing.
Enforcing statement-level inspection with hoop.dev
Stopping an automated client from deleting live tables requires a check on the connection itself. hoop.dev provides this check as an open-source proxy that sits next to the database or API. It serves as a sidecar next to Postgres or other databases. It reads protocol traffic as it moves between client and server.
The proxy sits on the wire, so hoop.dev guardrails check statements before they reach the database. An operator sets an ordered deny list based on statement effects. If an agent tries to drop a table, hoop.dev refuses the statement before it lands. It does the same if an agent runs an update or delete without a where clause. It returns the database native error format with the operator message. The agent reads the clear reason and can try a safe query without a dropped connection.
When teams need flexible agent workflows, the hoop.dev AI Analyzer can classify statement intent and risk. It does this by calling an operator-configured model provider. If a statement carries high risk, hoop.dev Reviews hold it on the connection until a person approves or denies it. In addition, hoop.dev records what ran and what it decided, resource by resource.
Learn how queries are checked by visiting the hoop.dev architecture page, or read the hoop.dev sidecar docs for setup guidance. Inspecting statements on the wire gives agents the access they need while stopping destructive commands before they run.
To see the code or test the proxy locally, visit the hoop.dev GitHub repository.
Frequently asked questions
Why are database roles not enough to stop agent accidents?
Database roles only set general permissions for an identity. They do not inspect individual statements on the fly. An account with edit rights can run a destructive statement just as easily as a safe query. A proxy on the connection checks each statement before execution.
What happens when hoop.dev blocks an agent query?
hoop.dev returns a standard database error using the native protocol of the database. It includes the custom text of the operator. The agent reads the refusal message directly and can choose a safe alternative.
What is complete mediation for AI agent access?
OWASP defines complete mediation as enforcing authorization in downstream systems rather than relying on the agent to police itself. The system checks every request against security policies before it runs.
In this post