All posts
Joe Connolly ai agents, api keys, security, deploying

AI agent API keys that can't delete production

An agent key on velixir can deploy, read logs and test releases. Anything that deletes or overwrites waits for a person to approve it first.

AI agent API keys that can't delete production

In April, an AI coding agent deleted a startup's production database in nine seconds. It was working in staging, hit a credential mismatch, went looking for a way round it, and found an API token in a file that had nothing to do with the task. The token worked. One API call later the database was gone, and so were the backups, because they lived on the same volume.

Nobody did anything unusual there. Agents read files, files contain keys, and API keys do whatever they're allowed to do. That's the part we wanted to change.

Why is a normal API key the wrong thing to give an agent?

Because an API key answers one question: is this caller allowed? It has no way to ask whether the caller should. A key scoped to one project still deletes everything in that project. That was fine when the only thing holding the key was a CI job running a script you wrote. It's a different situation when the thing holding it improvises.

Most of what an agent does with a key is exactly what you want it doing unsupervised: deploying, reading logs, checking a release. A tiny fraction is the stuff you'd want to see first. So that's how agent keys split it.

What is an agent key?

When you create an API key on velixir, you now choose who uses it: an AI agent or a person, script or CI. An agent key does everything its permission allows, with one difference. Anything that destroys or overwrites doesn't run:

  • deleting an app, a database, a cache, a volume or a custom domain
  • restoring a volume over its current files
  • applying or undoing a rewind, or discarding a copy

Instead, the API answers 202 with an approval link and a one-line summary of what was asked, like Delete the database shop-db. Nothing has changed. You get an email, the request waits on the Approvals tab under API keys (the sidebar shows a count), and when you approve it, it runs, as you. If nobody answers in 24 hours, it expires.

Agent keys also can't create or revoke API keys, so an agent can't hand itself a key without the approvals.

blog-agent-keys-twokey

What does the agent see?

The velixir MCP server knows about approvals. When a call needs one, the agent is told plainly that nothing happened and that it should send you the link, rather than being told it worked. It can check on the request with approval_status. The CLI does the same: instead of printing "Deleted", it tells you the action needs approval and where to approve it, and exits non-zero so a script doesn't carry on as if it had.

Asking twice gives the same request, not a pile of them, so an agent that retries doesn't spam you.

What if a person deletes something by mistake?

Approvals cover the agent. For everyone else, we changed what delete means. Deleting a database on velixir now keeps its backups for your plan's window (7, 14 or 28 days), and it can be restored from Recently deleted on the Databases page or with one API call. Persistent caches keep their snapshots the same way, and a deleted volume's snapshots can be restored into a new volume on the same app for a week.

So even the worst version of that April afternoon, the right key in the wrong hands and the delete confirmed, leaves you with something to bring back.

What agent keys don't do

They don't make a bad deploy safe. An agent key can still ship broken code, because shipping is the point. That's what Replay and Rewind are for: Replay tests a release against your real traffic before it goes live, and Rewind takes the app and its data back to a moment if something gets through.

They don't gate the dashboard either. If you're the one clicking delete, you're already the person we'd ask. Env var changes aren't gated, because they're how an agent configures what it deploys, and Rewind can bring the old ones back.

And they only protect you if you use them. A standard key handed to an agent is still a standard key.

How do I set one up?

Open API keys in the dashboard, create a key and pick An AI agent. Put it in your agent's environment as VELIXIR_API_KEY; for Claude Code and other MCP clients, npx -y @velixir/mcp picks it up. The API keys docs list exactly which calls need approval.


Got an app to ship? velixir hosts it in any language, on servers in the EU.

Start free - your first month's on us