How to prevent accidental deletion in AWS, Azure, and GCP
Preventing accidental deletion in the cloud means two separate things: making it harder to delete the wrong resource by mistake, and being able to get it back if someone does. Every major cloud gives you tools for both, but they are scattered across services, off by default, and none of them stop a legitimate user from running a destructive action on purpose. Here is what each cloud actually offers, where the gaps are, and what to do about the part the settings do not cover.
How do I prevent accidental deletion in AWS?
AWS has no single “undo” button. It has a pile of separate features, and you have to know each one exists.
For EC2, there is termination protection, a flag that blocks an instance from being terminated until you turn the flag off. For S3, the real protection is versioning combined with MFA delete, so an overwritten or deleted object can be recovered. AWS also has a Recycle Bin for EBS snapshots and AMIs, which holds deleted resources for a retention period instead of destroying them immediately. At the account level, Service Control Policies can deny specific delete actions across a whole organization.
Where it falls short: every one of these is opt-in and resource-specific. Termination protection does nothing for your RDS database. S3 versioning does nothing for your DynamoDB tables. And none of them help when the person deleting has the rights to delete and simply means to, which is the exact situation in most real incidents.
How do I prevent accidental deletion in Azure?
Azure’s main tool is resource locks. You put a CanNotDelete or ReadOnly lock on a resource, resource group, or subscription, and Azure refuses delete calls until the lock is removed. For storage specifically, blob soft delete keeps deleted data recoverable for a retention window you set.
Where it falls short: locks protect against the accidental click, but anyone with the right role can remove a lock and then delete. The lock is a speed bump, not a wall, and it does nothing about intent. Soft delete saves your blobs but not your databases or VMs.
How do I protect a GCP project from accidental deletion?
On Google Cloud, the tool most people miss is the project lien. A lien blocks deletion of an entire project until the lien is removed, which is genuinely useful because deleting a whole GCP project is a terrifyingly easy way to lose everything at once. Individual services add their own soft-delete windows on top.
Where it falls short: same story as the others. A lien stops the accidental project delete, but not a user with permission to lift it, and not a destructive action inside the project.
What about terraform destroy?
This one deserves its own mention because so many teams have been bitten by it. Terraform’s prevent_destroy lifecycle rule will make terraform destroy fail on a protected resource. It is worth setting.
But every honest guide to it admits the same gap: prevent_destroy only protects you inside Terraform. It does nothing if someone deletes the same resource from the console or the CLI. Your infrastructure code thinks the resource is protected while a human quietly removes it by hand, and now your state and your reality disagree.
The gap all of these share
Line them up and the pattern is obvious. Every native protection is either a per-resource flag you have to remember to set, or a lock that any sufficiently privileged user can remove. They are built to stop the accidental click on a specific resource. They are not built to stop a session that has legitimate access and is doing something destructive, whether by mistake, by a leaked key, or by an AI agent that was handed more permission than it should have had.
That is the whole reason the “junior dev deleted production” story keeps happening at companies that had backups and policies. The controls guard resources. The risk is sessions.
What actually closes it
Two changes cover the gap the native tools leave open.
First, stop handing out standing access to everything. If access is requested for a task and expires on its own, far fewer sessions can delete anything in the first place. That is what temporary, just-in-time access is for.
Second, watch the sessions that do have access, and judge what they are trying to do. Korvalis sits inside your own cloud, reads the intent of a live session, and when the session turns destructive it terminates it on its own, in seconds. It is not another flag on another resource. It is something watching the actions themselves, across the account, whoever is behind them.
You will still want versioning and backups. Those are how you recover. Think of Korvalis as the layer that tries to make sure you do not have to.
Frequently asked questions
Can you recover a deleted S3 bucket? If versioning was enabled before the deletion, you can recover the objects. If it was not, deleted objects are generally gone. This is why versioning has to be on before anything goes wrong, not after.
Does AWS have an undo button? No. AWS has separate recovery features per service, like S3 versioning, the Recycle Bin, and RDS snapshots. There is no single account-wide undo, which is why prevention matters as much as recovery.
What is the difference between a resource lock and preventing the action? A lock, like an Azure resource lock or a GCP lien, blocks deletion until someone removes the lock. Anyone with enough permission can remove it. Stopping the action itself means watching what a session is doing and intervening based on intent, not just on whether a flag is set.
How do I stop an AI agent from deleting production? Give the agent access that is scoped and temporary rather than standing, and put something in front of the actual actions that can stop a destructive session in real time. We wrote about how that works here.
If preventing this class of mistake is on your list, see what Korvalis includes or join the waitlist.