Incident response plan
Last updated 2026-09-25. Owner: founder. Review: every 12 months and after every SEV-1 or SEV-2. Not yet exercised (no tabletop test has been run). First tabletop: before the first live firm.
This plan is written for a one-person company. Where it says "counsel", that is outside counsel the founder must engage in advance; no counsel or incident-response firm is on retainer yet.
1. What counts as an incident
Any event that may have exposed, changed, destroyed or made unavailable customer data, or that shows someone got into a system they should not. Examples:
- Unauthorized access to the app, AWS, Neon, Netlify, Stripe, Resend, Sentry, GitHub or the founder's email.
- A leaked secret (API key, database URL, AWS access key,
KMS_DATA_KEY_CIPHERTEXT+ KMS access). - A bug that shows one firm's data to another firm, or shows data to the wrong role or branch.
npm run audit:verifyreports a broken hash chain.- An export or image fails its hash check.
- A subprocessor reports a breach affecting our data.
- A lost or stolen laptop or phone that has production access.
- Extended outage.
2. Roles
| Role | Who | Backup |
|---|---|---|
| Incident lead (decides, coordinates, keeps the log) | Founder | None today. Name a trusted technical contact with break-glass instructions (see access-control-policy.md). |
| Technical responder (contain, investigate, fix) | Founder | Outside incident-response firm (to be arranged) |
| Customer communication | Founder | — |
| Legal / regulatory advice | Outside counsel (to be engaged) | — |
| Evidence keeper | Founder | — |
With one person, the order matters: contain first, preserve evidence second, then notify. Do not spend hours investigating before containing.
3. Severity
| Level | Meaning | Examples | Response start | Customer notice |
|---|---|---|---|---|
| SEV-1 | Confirmed or likely unauthorized access to customer data, or data of one firm visible to another | Leaked DB credentials used; cross-tenant bug in production; hash chain broken | Immediately, any hour | Without undue delay, and within 72 hours of confirming |
| SEV-2 | Security control failed, no evidence of data access yet; or full outage > 4 hours | Leaked key with no sign of use; MFA bypass bug found; KMS key disabled | Within 4 hours | Within 72 hours if customer data could be affected |
| SEV-3 | Limited issue, no customer data at risk | Vulnerable dependency not reachable; partial outage | Next business day | Status note if customer-visible |
| SEV-4 | Informational | Scanner noise, phishing email not clicked | Log only | None |
When in doubt, pick the higher level.
4. Steps
4.1 Detect and open
- Open an incident log (a dated file in a private folder, not in the code repository): time, what was seen, by whom.
- Assign a severity.
4.2 Contain
Pick what applies:
- Credentials: rotate the leaked secret at the provider (AWS access key: deactivate, create new; Neon: reset the role password; Resend/Stripe/Sentry: roll the key), update Netlify, redeploy.
- App access: revoke all sessions for affected users (or all users) in the
Sessiontable; lock affected accounts; revoke examiner links. - Bad code: roll back the Netlify deploy to the last good one (one click), or take the site offline with a maintenance page.
- AWS: deactivate the app's access key; the bucket policy already blocks deletes, and locked objects cannot be destroyed.
- Founder device lost: revoke its sessions in Google, GitHub, AWS, Netlify, Neon; rotate secrets that were stored on it.
4.3 Preserve evidence
Before changing anything else, and in all cases within 24 hours:
- Neon: create a branch at the current point in time (and one just before the suspected start). Do not restore over the live database until the copy exists.
- Netlify: download deploy logs and function logs for the period.
- AWS: CloudTrail event history (90 days by default; a full trail is not yet configured), S3 access logs (kept ~7 years in the log bucket).
- App: export the
AuditLogrows for the period and runnpm run audit:verify; save the output. - Provider notices, emails and screenshots, with times.
- Store copies in a private, access-controlled location and note their SHA-256 hashes.
Records in S3 cannot be deleted, and record tables are insert-only, so an attacker using the app's credentials cannot erase the history they would want to hide.
4.4 Investigate
Establish: what happened, when it started and stopped, which firms, which records, whether data left our systems. Use the audit log (who viewed or exported what), S3 access logs, Neon and Netlify logs.
4.5 Notify
Customers (firms). CheckTrail commits to notify each affected firm's named security contact without undue delay and no later than 72 hours after confirming an incident that affected, or likely affected, that firm's data or the systems holding it. The first notice gives what is known; updates follow at least every 72 hours until closed. The notice includes: what happened, when, which data, what we have done, what the firm should do, and a contact.
Regulation S-P (flag for counsel). Our understanding is that the SEC's 2024 amendments to Regulation S-P require broker-dealers to:
- have written policies requiring their service providers to notify them as soon as possible and no later than 72 hours after becoming aware of a breach resulting in unauthorized access to a customer information system the provider maintains; and
- notify affected individuals whose sensitive customer information was, or is reasonably likely to have been, accessed or used without authorization, as soon as practicable and no later than 30 days after becoming aware of the incident, unless an exception applies.
CheckTrail's 72-hour customer commitment is meant to fit the first requirement. The firm, not CheckTrail, sends notices to its clients; CheckTrail must give the firm what it needs to do so within the 30-day window (which records, which clients, what data). Counsel to confirm the exact obligations, the compliance dates that apply to each customer, and whether any state breach laws also apply to CheckTrail directly.
Others, as counsel advises: law enforcement, the affected subprocessor, cyber insurer (none today).
Do not speculate in notices. Do not state that data was not accessed unless the logs show it.
4.6 Recover
Fix the cause, redeploy, verify (tests, npm run audit:verify, spot-check exports), restore
normal access, and watch closely for 14 days.
4.7 Post-mortem
Within 10 business days of closing a SEV-1 or SEV-2, write a blameless post-mortem and share a summary with affected firms on request:
- Timeline (detection, containment, notification, recovery), with times
- Root cause and contributing factors
- What data and which firms were affected
- What worked, what didn't
- Actions, each with an owner and a date
- Changes to this plan
Keep incident logs and post-mortems for at least 6 years.
5. Contacts (fill in)
| Who | How |
|---|---|
| Founder (incident lead) | phone / email |
| Backup technical contact | to be named |
| Outside counsel | to be engaged |
| Incident-response firm | to be arranged |
| AWS Support | console |
| Neon, Netlify, Resend, Stripe, Sentry support | per provider |
| Each customer's security contact | kept in the customer contract record |