SaaS Security Incident Response: Your First Hour Plan

A solo founder's security incident response plan: the first-hour checklist, breach notification obligations, the customer email, and the post-incident writeup.

· Justin Boggs

A red emergency pull lever mounted on a plain wall

Photo by Jason Leung on Unsplash

SaaS security incident response for a solo founder comes down to four moves in the first hour: confirm it's real, contain it, scope it, and start the notification clock. In that order. The instinct — mine, anyway — is to jump straight to fixing the bug, and that's the wrong first move, because a fix that overwrites your logs destroys the evidence you need to figure out what was actually taken. This post is the checklist I keep in a file called INCIDENT.md, plus the notification obligations that actually apply to a small SaaS, the customer email template, and the writeup you publish afterward.

TL;DR

  • Confirm before you act. Most "incidents" are misconfigurations. Reproduce it and check the logs before you wake anyone up.
  • Contain, then investigate. Rotate credentials and revoke sessions first; root-cause it second. Snapshot logs before anything expires them.
  • Write everything down as it happens. A timestamped append-only log is what turns a bad day into a defensible one.
  • The GDPR clock is 72 hours from awareness, not from resolution — and Article 33 explicitly lets you notify in phases.
  • Write the postmortem. Blameless, specific, published. It's the single best trust-recovery move you have.

Confirm it's real before you do anything else

Most alarms aren't incidents. A customer emails "I think I can see someone else's data." A monitoring alert fires at 3am. Someone posts on X that your app leaked something. Before you touch production, establish whether anything actually happened.

Three questions, in order. Can you reproduce it? Follow the exact steps the reporter described, in an incognito window, signed out. What do the logs say? Look for the specific request. Check whether it succeeded, what it returned, and whether the same pattern appears elsewhere. Is the scope one row or every row? A single misrouted record is a bug. A query missing a tenant filter is an incident.

The distinction matters because the response is completely different. A bug gets a fix and a changelog entry. An incident gets containment, evidence preservation, a notification decision, and a writeup.

Give yourself a severity scale so you're not making this call under pressure. Mine is four lines:

| Severity | What it means | Response | | --- | --- | --- | | SEV1 | Confirmed unauthorized access to customer data, or active attacker | Drop everything. Contain now. Notification clock starts. | | SEV2 | Credential exposed (key in a repo, leaked token), no confirmed access yet | Rotate within the hour. Investigate access logs. Probably notify. | | SEV3 | Vulnerability found, no evidence of exploitation | Fix on a normal timeline. Document. Usually no notification. | | SEV4 | Suspicious but unconfirmed | Investigate. Do not page anyone. |

Write this down before you need it. At 2am with adrenaline running, "is this a SEV1 or a SEV2" is a much easier question to answer than "how bad is this."

One more thing: start the incident log the moment you suspect SEV1 or SEV2. A plain text file, append-only, every entry timestamped. What you observed, what you did, what you saw next. It feels like bureaucracy for the first ten minutes and then becomes the most valuable artifact of the whole event — it's your timeline for the customer notice, your evidence for a regulator, and your memory when you write the postmortem three days later. Article 33(5) of the GDPR actually requires this documentation: the facts, the effects, and the remedial action taken, in enough detail that a supervisory authority can verify compliance.

The first hour, minute by minute

Horizontal timeline chart showing eight incident response tasks laid out across the first 60 minutes, from confirming the incident at T+0 through sending the customer notice at T+55

Two tasks run the whole hour: the incident log, and preserving evidence. Everything else is sequential.

T+0 to T+5 — Confirm. Reproduce. Read the logs. Assign a severity. If it's SEV3 or below, stop here and handle it normally.

T+5 to T+20 — Contain. The goal is to end the attacker's access, not to understand it yet. In practice, for a small SaaS, that's a specific list:

  • Rotate every API key and service credential that could plausibly be involved — Stripe, Supabase service role, Resend, anything in .env.local.
  • Revoke active sessions. In Supabase that's a global sign-out; every user has to log in again. Annoying, and worth it.
  • If a specific customer's API key leaked, revoke that key and nothing else. Don't nuke everyone for a single-tenant problem. (This is why customer-facing API keys need a per-key revoke button before you need it.)
  • If the vector is a code path, disable the feature behind a flag rather than shipping a rushed patch to production.

Rotate keys in a way that doesn't take you down. Stripe's best practices for managing secret API keys describes the pattern: when you roll a key, the old and new both work for up to 7 days, and you expire the old one once its request volume has been at zero. In a SEV1 you may not have 7 days — but you should still know which of your credentials support overlap and which are hard cutovers, before the incident. That's an afternoon of prep work, and it belongs alongside your secrets management setup.

T+15 to T+40 — Scope. Now figure out what was actually reachable. Which records, whose records, over what time window. Be precise: "an API key with records:read scope on one account, active between 14:02 and 14:26 UTC, could list that account's contact records" is an answer. "Some data may have been accessed" is not, and it's the sentence that turns a contained incident into a trust crisis, because customers assume the worst when you're vague.

T+20 to T+35 — Preserve evidence. Snapshot your logs to durable storage before retention windows eat them. Vercel and Supabase both roll logs off on a schedule, and free tiers roll them off fast. Take a database point-in-time snapshot too. You are not doing forensics right now; you're making sure forensics is still possible tomorrow.

T+35 to T+60 — Communicate. Draft the customer notice, decide whether a regulator gets one, and publish a status update. Details below.

That's the hour. Nothing in it requires a security team — it requires a written list, which is the entire point.

Who do you actually have to tell?

This is where founders freeze, usually because the legal reading is genuinely unclear and the internet is full of scary generalities. Here's the honest version for a small SaaS.

flowchart TD
    A[Confirmed unauthorized access] --> B{Personal data involved?}
    B -->|No — e.g. internal metrics only| C[Notify affected customers<br/>if contractually required]
    B -->|Yes| D{Do you have EU/UK users?}
    D -->|Yes| E[GDPR Art. 33: notify supervisory<br/>authority within 72h of awareness<br/>unless risk is unlikely]
    D -->|No| F[Check US state laws<br/>where your users live]
    E --> G{High risk to<br/>individuals' rights?}
    G -->|Yes| H[GDPR Art. 34: also notify<br/>affected individuals<br/>without undue delay]
    G -->|No| I[Authority only]
    F --> J[Notify affected residents.<br/>CA: sample copy to the AG<br/>if over 500 residents]
    C --> K[Publish status page update<br/>and postmortem]
    H --> K
    I --> K
    J --> K

GDPR. If any of your users are in the EU or UK, Article 33 applies. You notify the supervisory authority "without undue delay and, where feasible, not later than 72 hours after having become aware of it" — unless the breach is unlikely to result in a risk to people's rights and freedoms. Two details founders miss. The clock starts at awareness, not at resolution, so a week of investigation doesn't buy you a week of silence. And Article 33(4) explicitly permits notification in phases: if you don't have complete information at hour 71, you file what you have and supplement it. Late notification isn't fatal either — it just has to be accompanied by reasons for the delay.

Article 34 is separate. If the breach is likely to result in a high risk to individuals, you also have to tell the individuals themselves, without undue delay. Exposed password hashes or payment details clear that bar; a leaked list of internal feature-flag names probably doesn't.

If you're a processor rather than a controller — you're processing data on behalf of business customers, which describes most B2B SaaS — your obligation runs to your customer, not the regulator. Notify them without undue delay so they can meet their own 72 hours — the European Data Protection Board's breach notification guidelines recommend telling the controller promptly and following up in phases. My starting point on all of this is in GDPR basics for indie SaaS.

US state law. There's no single federal breach law for a typical SaaS; it's state by state, based on where your users live, not where you are. California's is the one most people encounter: Civil Code 1798.82 requires notifying any California resident whose unencrypted personal information was acquired by an unauthorized person, "in the most expedient time possible and without unreasonable delay." If you notify more than 500 California residents about a single breach, you also submit a sample copy of that notice to the California Attorney General, who publishes it in a searchable public database.

Your contracts. Read your own terms and any enterprise agreements you've signed. Business customers frequently negotiate notification windows tighter than any statute — 24 hours is common. That's a contractual obligation regardless of what the law says.

I'm a founder, not a lawyer, and none of this is legal advice. For a SEV1 involving personal data, an hour with a privacy attorney is genuinely worth the money — and it's much cheaper if you've already got a written timeline to hand them.

The customer email

Send it before you've fixed everything. The instinct to wait until you have a complete story is the instinct that turns a security incident into a trust incident, because customers find out from someone else and then wonder what else you sat on.

Four things it needs: what happened, what data was involved, what you did, what they should do. In that order, in plain language, no hedging.

Subject: Security incident affecting your [Product] account — action needed

Hi [Name],

On August 27 at 14:02 UTC, an API key belonging to your account was used
from an IP address we don't recognize. Between 14:02 and 14:26 UTC, that
key was used to list contact records in your workspace.

What was accessible: names, email addresses, and company names for the
1,240 contacts in your workspace. Passwords were not involved — we don't
store them in a form that key could reach. No payment information was
accessible.

What we did: we revoked the key at 14:31 UTC and confirmed no further
requests succeeded after that. We've preserved the full request log.

What you should do: review the API keys in your settings and delete any
you don't recognize. If you shared that key with a contractor or committed
it to a repository, rotate anything else that lived alongside it.

We'll publish a full writeup within 7 days. If you have questions, reply
to this email and it comes straight to me.

— Justin

What makes that email work is that every claim is specific and checkable. Timestamps, record counts, what was not affected. The "what was not affected" line does a lot of work — it's the difference between a customer who's annoyed and a customer who's imagining the worst case.

What it deliberately avoids: "out of an abundance of caution," "we take security seriously," "we have no evidence that," and the passive voice. Those phrases read as evasion because they usually are. Send it from your own address, not noreply@, and be ready for the replies — founder-led support is an advantage here, and the same instincts from founder-led support apply under pressure.

Publish a status page update in parallel so customers who don't check email have somewhere to look. If you don't have one yet, that's a 20-minute setup, and doing it during an incident is not the ideal time to learn the tool.

The postmortem

Write it within a week. Publish it publicly unless there's a specific reason not to.

The structure that works is the one large infrastructure companies converged on — NIST's SP 800-61r3, finalized in April 2025, folds incident response into the Cybersecurity Framework's six functions and treats "improve" as a continuous outcome rather than a one-time report. That's the mindset: the postmortem is an input to your next quarter, not a compliance artifact.

Five sections:

  1. Timeline. Timestamped, from first signal to resolution. This is where your incident log pays for itself.
  2. Impact. Exactly who and what was affected, with numbers.
  3. Root cause. The actual technical cause. Not "human error" — the missing tenant filter, the over-scoped key, the misconfigured RLS policy.
  4. What we changed. Specific, shipped fixes with dates. Not intentions.
  5. What we're still working on. Honesty about the remaining gaps builds more trust than a clean bill of health nobody believes.

Blameless means you name the system, not the person. "A query in the export route was missing its organization_id filter, and our test suite had no multi-tenant fixture that would have caught it" is a root cause. "A developer forgot a filter" is a dead end — it produces no fix, and it teaches everyone to be quiet about mistakes.

The uncomfortable truth is that a well-written postmortem often increases trust. It's evidence you understand your own system, that you tell the truth when it's expensive, and that the specific hole is closed. Vague silence after an incident does the opposite.

Then close the loop: turn each "what we changed" item into an actual task, and add a regression test for the root cause. An incident you can't reproduce in a test is an incident that can recur. If you're using an AI assistant, this is exactly the moment to have it write the test — describe the vulnerable path precisely and ask for a failing test first, the workflow in AI-generated tests for non-devs.

Frequently asked questions

Do I need a formal incident response plan as a solo founder?

You need a written checklist, not a formal plan. One markdown file with your severity scale, your containment steps, your notification decision tree, and the credentials that need rotating. That file does 90% of what a heavyweight plan does, and you'll actually read it at 2am.

What counts as "becoming aware" for the GDPR 72-hour clock?

Awareness means you have a reasonable degree of certainty that a breach occurred — not the moment you resolve it, and not the moment you have every detail. A short investigation to confirm a vague report is legitimate; a week of silence while you build the fix is not. Article 33(4) exists precisely so you can file incomplete information on time and supplement later.

Should I take the service offline during an incident?

Rarely. Taking the whole app down punishes every customer for a problem that usually affects one code path. Disable the specific feature behind a flag instead. Reserve a full shutdown for an active attacker you can't otherwise lock out.

Do I have to notify if the data was encrypted?

Encryption materially changes the risk analysis and, under several US state laws including California's, unencrypted data is the trigger. But "encrypted at rest" doesn't help if the attacker had valid application credentials and read the data through your API — which is the common case. Ask whether the attacker could read the plaintext, not whether the disk was encrypted.

How do I keep an attacker from getting back in?

Rotate every credential that could plausibly be involved, not just the one you found. Revoke active sessions. Then check for persistence: new API keys, changed webhook endpoints, added team members, modified email-forwarding rules. Attackers create their own access before you notice the original hole.

What should I do the week after?

Ship the fixes you promised, publish the postmortem, and spend one afternoon on the prevention item you keep deferring. After my own close calls that was an audit log and alerting on unusual API key usage — both boring, both things I'd have built years earlier if I'd known how much calmer they'd make the next incident.

Wrapping up

A SaaS security incident response plan for a small company isn't a document you commission. It's a checklist you write on a quiet afternoon and hope you never open: a severity scale, a containment list, a notification decision tree, and an email template. Thirty minutes of prep converts the worst hour of your year from improvisation into execution.

The four moves, in order: confirm, contain, scope, notify. Keep a timestamped log the whole way through. Tell customers specifically what happened before you've finished fixing it. Publish the postmortem. None of it is clever, and all of it is much harder to invent while your hands are shaking.

If you're setting up the boring infrastructure that makes this survivable — audit logging, credential handling, transactional email — Coding Capybaras is the free boilerplate I built for non-technical founders, and it ships with the audit log and secrets layout referenced above.