/ projects / postmortemforge

PostMortemForge

Client-facing incident post-mortem reports, generated from a structured schema

Active
Python FastAPI Jinja2 JSON Schema
42 kill-chain stage blocks ATT&CK coverage grid Self-contained HTML output

Built into it

  • 42-block kill-chain stage library
  • ATT&CK coverage grid + dwell-bar
  • Prefilled BEC and quishing templates
PostMortemForge

Problem

After a real incident, clients want a post-mortem they can read at the board level and trust at the analyst level. Two failure modes are predictable: write the report from scratch each time and the structure drifts between analysts; fill out a Word template and you end up with inconsistent jargon, broken kill-chain narratives, and ATT&CK references that don’t match the actual investigation. Either way the report eats hours, and the second one for the same client doesn’t visibly resemble the first.

Approach

PostMortemForge takes a structured incident JSON and renders a self-contained HTML report — CSS inline, SVGs inline, system fonts only — that’s safe to email as an attachment. PDF export is browser print-to-PDF; no headless-Chrome dependency, no cloud rendering service.

The authoring UI is a FastAPI backend with a single-file vanilla-JS frontend. Analysts drag stages from a 42-block library onto the incident canvas. Each stage is pre-mapped to a MITRE ATT&CK tactic, so the coverage grid populates as the narrative is built.

schema/
  incident.schema.json       JSON Schema for the Incident type
  stage_library.json         42 pre-built kill-chain stage blocks
  mitre_techniques.json      Bundled ATT&CK technique lookup
  jargon_glossary.json       10-term plain-language glossary
templates_library/
  quishing.json              Prefilled 10-stage QR-phishing + mobile-pivot
  bec.json                   Prefilled 11-stage vendor-invoice BEC via ATO

Two prefilled templates ship in the box — quishing and a vendor-invoice BEC via account takeover — so the most common incident shapes are five clicks from a starting draft instead of a blank canvas. The rendered report includes an ATT&CK coverage grid, a dwell-bar visualization, and an anomalous sign-in trace drawn from a coarse continent-outline dataset (no third-party map service, no API key).

Outcome

A report that used to take half a day to assemble lands as a draft in fifteen minutes. Reports for the same client share visual and structural identity across incidents, and client-facing language stays consistent because the jargon glossary is enforced at render time, not left to the author’s memory.

What’s next

Per-client style overrides — colors, logo lockup, contact block — without breaking the self-contained-HTML constraint are the next priority. After that, an evidence-attachment pipeline that bundles redacted log excerpts as inline base64 instead of separate file attachments.