15 KiB
status, playbook-section, title, gdpr-articles, last-reviewed
| status | playbook-section | title | gdpr-articles | last-reviewed | ||
|---|---|---|---|---|---|---|
| template | 20 | Security Incident & Personal Data Breach Runbook |
|
[FILL IN: YYYY-MM-DD] |
Security Incident & Personal Data Breach Runbook
Template status — fill every
[FILL IN: …]marker before use. Cross-references below point to shipped code and ADRs; do not change them.
1. Purpose & Scope
This runbook governs the detection, triage, containment, notification, and post-mortem of security incidents and personal data breaches affecting [FILL IN: product / organisation name].
In scope: any event that may have compromised the confidentiality, integrity, or availability of personal data processed by this system, including unauthorized access, exfiltration, accidental exposure, and ransomware.
Out of scope: non-PII service disruptions (handle via standard on-call runbook). Escalate to this runbook when PII impact cannot be ruled out.
2. Severity Classification
| Level | Definition | Example |
|---|---|---|
| P0 — Critical | Confirmed exfiltration or mass exposure of PII | Database dump on public host |
| P1 — High | Suspected breach; blast radius unknown | Anomalous EXPORT audit entries for non-admin actor |
| P2 — Medium | Contained misconfiguration; no confirmed PII leak | Stale presigned URL exposed to wrong tenant |
| P3 — Low | Near-miss; no PII accessed | Failed injection attempt blocked by rate-limit |
3. Roles & Contacts
| Role | Name | Contact |
|---|---|---|
| Incident Commander | [FILL IN: name] | [FILL IN: contact] |
| Data Protection Officer | [FILL IN: name / DPO provider] | [FILL IN: contact] |
| Legal / Counsel | [FILL IN: name] | [FILL IN: contact] |
| Engineering Lead | [FILL IN: name] | [FILL IN: contact] |
| Communications Lead | [FILL IN: name] | [FILL IN: contact] |
Supervisory Authority (SA):
- Authority name:
[FILL IN: e.g. ICO / CNIL / BfDI] - Online notification portal:
[FILL IN: URL] - Emergency phone:
[FILL IN: number]
4. Phase 1 — Detection
4.1 Automated signals
This template ships two automated detection surfaces. Check both when an alert fires.
Sentry error alerting (ADR-014)
Every unhandled exception in apps/web-next, apps/cms, and apps/web-tanstack is captured via ILogger.captureException and routed to Sentry (docs/decisions/adr-014-instrumentation-sentry.md). Configure alert rules in Sentry for:
- Spike in
4xx/5xxon auth or DSR routes - New issue fingerprints in production environment
- Volume anomaly on
[FILL IN: Sentry project slug]
Verify DSNs are configured:
# Each app has its own Sentry project
echo $WEB_NEXT_SENTRY_DSN
echo $CMS_SENTRY_DSN
echo $WEB_TANSTACK_SENTRY_DSN # if TanStack Start app is in use
All three must be non-empty in production. A missing DSN silently disables capture for that app.
Audit log anomalies (ADR-018)
The audit channel (docs/decisions/adr-018-audit-and-compliance.md) records every AuditAction emitted by feature use cases via AuditLogProtocol.record(). Actions relevant to breach detection:
AuditAction |
Breach signal |
|---|---|
EXPORT |
Mass export by non-admin actor or from unexpected IP |
VIEW |
High-frequency reads on a single actorId |
PERMISSION_CHANGE |
Privilege escalation outside change-management window |
DELETE |
Bulk delete with no corresponding DSR request |
Query the Payload audit logs collection or the aggregated cold archive ([FILL IN: log aggregation URL, e.g. Vector / Fluent Bit sink]) for anomalies. Correlate with OTel correlationId (trace ID auto-populated by TraceIdEnrichingAuditLog).
Rate-limit exhaustion (ADR-025 § Epic C)
The rate-limit primitive (IRateLimit in core-shared/rate-limit, see docs/guides/rate-limiting.md) emits { allowed: false, remaining: 0, resetAt } when a budget is exhausted. Repeated exhaustion on auth or DSR endpoints may indicate credential-stuffing or automated exfiltration.
Check budget tables declared in feature manifests (rateLimit: { window, budget }) against observed traffic in [FILL IN: metrics dashboard URL].
Security header violations
HSTS, X-Frame-Options, and CSP headers are emitted by the security-headers middleware (docs/guides/security-headers.md). CSP violation reports (if report-uri is configured) surface attempted XSS. Check [FILL IN: CSP report endpoint / dashboard].
4.2 Manual discovery
If detection was by human observation (e.g., responsible-disclosure report, darknet alert):
- Log the reporter's contact and discovery timestamp.
- Do not confirm or deny breach details to the reporter until DPO is engaged.
- Proceed to Phase 2.
5. Phase 2 — Triage
Target time: within [FILL IN: e.g. 2 hours] of detection.
5.1 Triage checklist
- Page Incident Commander and DPO.
- Open incident channel:
[FILL IN: e.g. #incident-YYYYMMDD in Slack / Teams]. - Document initial facts: detected at, detected by, affected system(s).
- Classify severity (§ 2).
- Determine if personal data is involved (see § 5.2).
- Initiate 72-hour DPA notification clock if P0 or P1 (§ 7.1).
5.2 PII impact assessment
Use the generated data map (compliance/data-map.yml, generated by pnpm compliance:data-map from Payload custom.pii field tags) to enumerate which collections and fields may be affected. Cross-reference with the scope of the incident (endpoint, DB table, S3 bucket, etc.).
Key questions:
- Which
piiCategoryvalues are in the affected scope? (e.g.contact-email,identification-name) - Are any
restrictable: truesubjects affected (i.e. users who invoked Art. 18)? - Was the
auditLogscollection itself compromised? (Audit trail integrity is required for Art. 33 notification.)
6. Phase 3 — Containment
Target time: within [FILL IN: e.g. 4 hours] of confirmation for P0/P1.
6.1 Immediate actions
- Revoke or rotate compromised credentials (
[FILL IN: credential management system]). - Block actor at network/WAF level if attack is ongoing (
[FILL IN: WAF / CDN control panel URL]). - If a specific
actorIdis confirmed malicious: suspend account in Payload admin (apps/cms, port 3001). - If a tRPC or REST route is the attack vector: deploy an emergency rate-limit tightening or disable the route (
[FILL IN: deployment method]). - Preserve evidence: take read-only snapshots of affected tables, CloudWatch / log streams, and network flow logs before any cleanup.
6.2 Audit trail preservation
The audit log collection is append-only (update: () => false Payload access rule per ADR-018). Do not attempt to delete or modify audit entries. If the audit collection itself is a target, freeze DB-level access and take a snapshot:
# [FILL IN: adapt to your database provider]
pg_dump --schema-only --table=audit_logs $DATABASE_URL > audit_logs_schema_snapshot.sql
pg_dump --data-only --table=audit_logs $DATABASE_URL > audit_logs_data_snapshot.sql
7. Phase 4 — Notification
7.1 Regulatory notification deadlines
| Obligation | Deadline | Trigger |
|---|---|---|
| GDPR Art. 33 — notify Supervisory Authority | 72 hours from becoming aware | Any breach involving personal data unless unlikely to risk rights/freedoms |
[FILL IN: national DPA requirement] |
[FILL IN: e.g. 24 hours] | [FILL IN: condition] |
| GDPR Art. 34 — notify affected data subjects | Without undue delay | High risk to rights and freedoms |
Clock start: the moment the organisation "becomes aware" — typically when the Incident Commander or DPO confirms the incident in § 5.1, not when it was first detected.
7.2 Supervisory Authority notification (Art. 33)
Prepare the notification using the SA's online portal ([FILL IN: URL]). Required fields per Art. 33(3):
- Nature of the breach (categories and approximate number of records / data subjects)
- Name and contact details of DPO:
[FILL IN: DPO name, email, phone] - Likely consequences of the breach
- Measures taken or proposed
Attach:
- Incident timeline (from detection to containment)
- Affected
piiCategoriesfromcompliance/data-map.yml - Audit log extract covering the incident window (redact unrelated subjects)
If full facts are not available within 72 hours: submit an initial notification marked "partial" and follow up without delay. GDPR Art. 33(4) explicitly permits phased notification.
7.3 Data subject notification (Art. 34)
Threshold: notification is required when the breach is likely to result in high risk to the rights and freedoms of individuals (e.g. identity theft, financial loss, discrimination).
- Drafting:
[FILL IN: communications lead]drafts notice in plain language. - Channel:
[FILL IN: e.g. in-app banner + email via transactional provider] - Content: nature of breach, DPO contact, likely consequences, mitigation steps.
- Timing:
[FILL IN: target send window, e.g. within 48 hours of Art. 33 notification]
7.4 Internal stakeholder notification
| Stakeholder | When | Channel |
|---|---|---|
| Executive team | P0/P1: immediately | [FILL IN] |
| Customer success | Before customer-facing comms | [FILL IN] |
| Board / audit committee | Within [FILL IN] hours |
[FILL IN] |
8. Phase 5 — Post-mortem
Target: within [FILL IN: e.g. 5 business days] of containment.
8.1 Post-mortem checklist
- Timeline reconstruction (detection → triage → containment → notification).
- Root cause analysis (five-whys or equivalent).
- Blast radius: confirmed data subjects affected,
piiCategoriesexposed, duration of exposure. - Audit log review: were anomalous
AuditActionentries present before detection? Werefrom.ipTruncatedvalues suspicious? - Control gaps identified.
- Remediation actions with owner and deadline.
- Lessons learned.
8.2 Remediation tracking
Document each action in [FILL IN: issue tracker, e.g. Linear / GitHub Issues] with:
- Linked ADR or guide (e.g. ADR-018, ADR-014)
- Owner
- Target date
- Verification step (e.g.
pnpm fallow:auditgreen, new test added)
8.3 Mandatory follow-up with Supervisory Authority
If the Art. 33 notification was submitted as "partial", file the complete notification with the SA by [FILL IN: agreed follow-up date].
9. Appendix — Command Reference
# Inspect running apps and their Sentry DSN status
echo $WEB_NEXT_SENTRY_DSN && echo $CMS_SENTRY_DSN
# Run fallow audit to surface dead exports / drift before post-mortem PR
pnpm fallow:audit
# Regenerate data map to confirm affected PII fields
pnpm compliance:data-map
# Re-emit all compliance artifacts (data-map + retention-policy + sub-processors)
pnpm compliance:emit-all
10. Document Control
| Field | Value |
|---|---|
| Owner | [FILL IN: DPO or Engineering Lead] |
| Review cycle | [FILL IN: e.g. annual or after every P0/P1] |
| Next review date | [FILL IN: YYYY-MM-DD] |
| Cross-references | docs/decisions/adr-018-audit-and-compliance.md, docs/decisions/adr-014-instrumentation-sentry.md, docs/decisions/adr-025-eu-compliance-baseline.md, docs/guides/audit-and-compliance.md, docs/guides/rate-limiting.md, docs/guides/security-headers.md |