Something is broken or exposed, and the strong instinct is to work out how it happened. That instinct is the expensive one. Understanding takes hours and the damage continues while you read. This page is an order of operations you can follow while your judgement is poor.
The idea
Work outward from the damage. Stop it spreading, cut off whatever access was gained, then find out how far it reached, then repair, and only then explain. The order matters more than the speed: containing before you understand costs you an hour of downtime, while understanding before you contain costs you everything that gets copied meanwhile. Write down what you do as you do it, with timestamps: you will need that record when you tell people, and you will not remember it accurately tomorrow.
1 contain take the surface down or roll the deploy back
|
2 rotate new key, deploy, revoke the old one,
then find what the holder created
|
3 scope logs: what was accessed, by whom, between when and when
|
4 restore from backup, into a copy first
|
5 tell affected users, and the regulator if required
|
6 write up one page, next week, on what would have caught itHow it works
Containment is whatever makes the damage stop now, and what that is depends on what went wrong. If what leaked is a credential, rotating it is the containment, so start at step two: rolling back a deploy does nothing to somebody already holding the key. For a bad deploy, containment is rolling back to the previous version rather than fixing forward, because a rollback has a known outcome and a fix does not. Vercel and Netlify keep previous deployments and promote one back with a button. On your own server it is stopping the service or pointing the domain at a holding page. For an exposed endpoint, taking it or the whole site offline for twenty minutes is a fair trade. Downtime is recoverable.
Rotation follows immediately. If a .env file was committed, every value in it is compromised,
including the database password and the webhook secret, so rotate the whole file rather than the one
key you noticed.
Rotation stops the key, not somebody who already used it. A secret key with full database access can issue a second key, add an admin user, or write a row that grants access later, and none of those die when the leaked key does. After rotating, look for what was created while they were in: delete API keys you did not issue, check the dates on admin and service users, and read recent grants. If you find one, the exposure is ongoing.
Scope is the step people skip, and it decides what you owe other people. Your provider's logs are the evidence: Supabase, Vercel and your payment provider all keep request or audit logs, though retention on a free plan can be short enough that a leak found a week late is already invisible. You want three answers. Which records could have been reached, from when to when, and whether anything was actually read or changed rather than merely exposed.
Restoring belongs after scope: a backup written over a live database overwrites the good rows created since the incident began. Restore into a separate database first, then copy back only the rows you identified as lost.
Telling people is where a data incident stops being only your problem. Under Article 33 a personal data breach must be reported to your supervisory authority without undue delay and where feasible within 72 hours of becoming aware of it, unless the breach is unlikely to result in a risk to the people involved. That clock starts the moment you become aware, not when you finish investigating, so a scope step still running does not pause it. Article 34 requires telling the affected people directly when the risk to them is high. Your supervisory authority is the data protection authority of the EU country you are established in. If you are outside the EU and only serve people in it, there is no single home authority, and you notify each country's authority whose residents are affected.
What to do
- Note the time you found out. That timestamp, not the time you start fixing, is when the 72-hour clock began. Then contain: roll back, or take the surface offline.
- Rotate every credential that shared a file with the exposed one, then check the account for keys, admin users and grants you did not create.
- Pull the logs for the window and save them outside the affected system, before retention deletes them.
- Restore into a separate database, confirm it, then move back only what was lost.
- Notify, if personal data was involved and the people involved are plausibly at risk, counting from the timestamp in step one. Say what happened, what data, when, what you have done, and what they should do. If step three ended in "I cannot tell", treat the whole affected dataset as involved and say so.
- Write one page next week on what would have caught it.
Where it breaks
This order assumes two things many small projects do not have: a backup you have actually restored at least once, and logs with enough retention to cover a leak you found late. Both are checkable in ten minutes on a normal afternoon, and that is the thing to do today if nothing has gone wrong yet. Open your host's log settings and read the retention number, and read Backups. Without them, step three ends in "I cannot tell", which does not reduce what you owe people, it widens it. The other failure is the fix that reintroduces the problem, deployed at speed by someone tired. Once the damage has stopped, stop.