post-incident review template for security events
A post-incident review template and process for security events: rebuilding the timeline from logs, filling in a blameless template covering summary, impact, root cause, and action items, assigning owners and dates, and sharing learnings org-wide. Use after a security incident closes, for near-misses, or vendor-caused events. Triggers: 'postmortem template security', 'incident review'. Not for: active incidents, customer breach notifications.
post-incident review template for security events
TL;DR
Do the review within a week while memories are fresh, keep it blameless, and end with action items that have owners and dates. The template below covers what happened, the timeline, impact, root cause, and what changes. A review without assigned follow-ups is just storytelling.
post-incident review template for security eventsUse this when
- A security incident just closed and you need to run the review
- You want a standard template so reviews are comparable over time
- Leadership asks for a written account of what happened
- You are building a habit of learning from near-misses, not just breaches
Not for this skill when
- The incident is still active (finish responding first)
- You need a customer-facing breach notification (different document, legal involved)
- You want a root-cause method deep dive (5 whys is covered briefly here)
- The event was a drill (use the drill log format instead)
Steps
1. Reconstruct the timeline from logs, not memory
Pull the actual timestamps: first malicious activity, detection, acknowledgement, containment, recovery. Memory lies about times; logs do not.
grep -Ei 'suspicious|unauthorized|failed' /var/log/auth.log | head -50Expected: concrete timestamped events you can order. Mark each entry as confirmed (log-backed) or reported (human memory) so the review does not treat guesses as facts.
2. Fill in the template
Use the structure below. Keep it factual and blameless: describe what the system allowed, not who messed up.
Post-incident review: [short title]
Date of incident: [date]
Severity: [sev level]
Lead: [name]
Status: [open/closed]
Summary
[2-3 sentences: what happened, in plain language]
Timeline (all times UTC)
- [time] [event, with log source]
- [time] [event, with log source]
Impact
- Data: [what data was touched, or "none confirmed"]
- Systems: [what was affected]
- Customers: [who noticed, or "none"]
Root cause
[the underlying cause, and the cause behind that, 2-3 levels deep]
What went well
- [thing 1]
What went badly
- [thing 1]
Action items
- [ ] [fix] | owner: [name] | due: [date]
- [ ] [fix] | owner: [name] | due: [date]
Follow-up review date: [date, 30 days out]Expected: every section filled, no blanks left as "TBD" except explicitly deferred items with a date. If you cannot fill Impact honestly, write "unknown, investigation continuing" rather than "none".
3. Run the review meeting blameless
Walk through the timeline, then ask "what made this the reasonable thing to do at the time" for every human action. The goal is system fixes, not culprits.
printf 'attendees: [names]\ndecisions: [list]\n' | tee -a review-notes.txtExpected: a notes file with who was there and what was decided, so the review is auditable later. If the conversation turns to who instead of what, the facilitator redirects: what in the system allowed it, what check was missing, what default was wrong.
4. Assign every action item an owner and a date
An action item without an owner is a wish. Each fix gets one name and one due date, and the lead tracks them to completion.
echo "[date] PIR action items: [N] open, [N] closed" | tee -a pir-tracking.txtExpected: a tracking line updated weekly until every item is closed. Items that slip get re-dated explicitly, not silently.
5. Share the learnings wider than the incident team
Strip sensitive details and share the lessons with the broader engineering org. The team that was not in the incident is the team most likely to repeat it.
printf 'share-out: [channel], [date], sensitive details removed: yes\n' | tee -a pir-tracking.txtExpected: a short writeup posted where engineers will actually see it, covering what broke and what changed. Over time these build the org's institutional memory.
Variant: near-miss review
Same template, lighter: summary, timeline, "how we got lucky", and the fixes that remove the luck. Near-misses are free lessons; most orgs waste them.
Variant: vendor-caused incident
Add a section on the vendor: what they told you and when, whether their timeline matches yours, and what changes on your side (monitoring, contract terms, contingency plans). You cannot fix their systems; you can fix your dependence on them.
Variant: executive summary version
One page: what happened, customer impact, root cause in one sentence, what you are doing about it with dates. No log excerpts, no jargon. Write it after the full review, not instead of it.
Why this happens
Incidents keep recurring because the learning never gets written down or assigned. The same misconfiguration causes three incidents in two years because each response fixed the symptom and nobody asked why the system allowed it. The post-incident review exists to convert an expensive event into durable system changes, and the template exists so the review happens the same way every time instead of depending on who runs it.
Edge cases and pitfalls
- Running the review too late: after two weeks the details are gone and the urgency is gone; schedule it within days of closure.
- Blame creep: "human error" as a root cause ends the inquiry; ask what made the error possible and easy.
- Action items that are actually projects: split them; a 3-month "improve monitoring" item will never close.
- Sensitive incidents: limit distribution of the full review, but still do it; secrecy and learning can coexist with a redacted share-out.
- Do not skip the "what went well" section; you need to know which defenses to keep funding.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_FVjncE2eV7iiITUMn8iPRw
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.