This is an offline single-HTML app. No data goes to or from the internet — no server, no account, no telemetry. Your engagements live in your browser's localStorage, and any evidence files you attach live in its IndexedDB — on this device, in this browser, and nowhere else.
Purple-team records name real hosts and controls. This data is sensitive, and it is YOUR responsibility.
Clearing this site's data, opening it in a private window, switching browsers, or losing this device erases everything. Back up regularly — the topbar Export button saves a .pumapack you can re-import or drag back onto the window.
PumaPurple — Help & shortcuts
PumaPurple tracks a purple-team engagement: a list of adversary actions, each scored on two independent questions — did a control stop it, and did the SOC see it. No server, no account, no telemetry.
Two axes, four outcomes. Every test rolls up to Prevented, Alerted, Logged, or Missed. Logged is the one that earns its keep: the telemetry was there and nothing fired. That's a tuning job. Missed is a visibility gap. Different teams, different budgets.
Result is two halves — prevention on the left, detection on the right — so you can see at a glance that a test was blocked and alerted, or blocked and invisible. It reads only. Scoring happens in the test itself, where the ratings, severity and evidence live, so a stray click in the grid can't rewrite a result you already recorded.
Start / Stop / Restart stamp the timestamps that let you find the action in your logs. They work on the selection too, so you can start twenty tests at once.
Re-tests carry their lineage. Duplicate a test and the copy remembers what it re-runs, showing the old result beside the new one and whether the gap actually closed. That count — gaps closed, not gaps found — is what the engagement is judged on.
Time to detect is optional. Stamp when the alert really fired and you get the interval from the start of the action; leave it and the detection is taken as real-time, which is the usual case. The stats say how much of the average was measured rather than assumed.
ATT&CK matrix — the techniques you actually tested, grouped by tactic and coloured by their worst result, with your coverage counted against the full Enterprise catalogue. Click a cell to filter the grid.
Evidence — attach screenshots and exports, or just paste or drop one onto the open test; each file is hashed with SHA-256 so the report can prove the artefact it cites is the artefact you collected.
Hand off the gaps. Right-click a gap — in the grid or the Stats gap list — to copy it as a detection ticket: the technique, what was run, the result, and the specific ask, ready to paste into a tracker.
Command palette (⌘/Ctrl+K) jumps to any view, any test, or any action without leaving the keyboard.
Engagements are workspace tabs, each with its own asset lists (sources, targets, tools, controls) and tags.
Export to Markdown, CSV, JSON, .xlsx, an ATT&CK Navigator layer, or a full .pumapack backup (⌘/Ctrl+S).
New to purple teaming? The Method tab is a short walkthrough. See the Keyboard tab for shortcuts.
Running a purple-team engagement
Purple teaming isn't red team versus blue team. Both sides sit in the same room, run a known action, and watch together to see what the defences actually did. The output isn't a win or a loss — it's a list of specific, fixable gaps.
Scope it. Pick a threat worth emulating and list the actions. One test = one ATT&CK technique, named concretely enough to re-run: Registry Run Key — Admin (LOLBin) beats persistence test. Define your assets first — the hosts you'll run from and against, the tooling, and the controls you're measuring — so every test scores against the same vocabulary.
Say what you're proving. Set Focus to Prevent or Detect before you run. A test with no stated intent can't fail, and won't appear in your gap list.
Run it and stamp it. Hit Start, execute the action, hit Stop. That start/stop window is what makes the action findable in the logs an hour later, when you're reconstructing what the SIEM saw.
Score both axes honestly. Prevention first: blocked, partially blocked, or not at all. Then detection — and be strict about the difference between Alerted (someone was told) and Logged (the data existed, nobody was told). Collapsing those two is the most common way a purple-team report overstates a SOC's maturity.
Rate the quality, not just the outcome. An alert that fires four hours late with no context is not a 5. The ratings are where that nuance lives.
Tune, then re-test. This is the part that makes it purple. Write the detection, then duplicate the test — the copy remembers what it re-runs — and prove the fix. The re-test shows the old result beside the new one and the Stats view counts the gaps you closed. A gap that was closed and re-verified is worth more than ten that were merely found.
Record a detection time when it was slow. An alert that fired four hours after the action is a different finding from one that fired in seconds, and the ratings alone won't carry that. Stamp the alert time on the ones that dragged; leave the rest, which are assumed to have been near-immediate.
Report the gaps. The Stats view ranks everything focused on prevention or detection that achieved neither, worst urgency first. That list is the deliverable; the rest is evidence for it.
Coverage is a trap worth naming: a fully green matrix means you tested what you thought to test. It says nothing about what you didn't.
Where your engagements live
Everything is stored in your browser — engagements in localStorage, evidence files in IndexedDB — on this device and this browser only. Nothing is uploaded anywhere.
This is the whole database. If you clear site data, use a private window, switch browsers, or lose the device, your engagements are gone. Back up regularly.
Backing up
The Export button writes a .pumapack containing every engagement; ⌘/Ctrl+S saves a quick backup. Restore with Import, or by dragging the file onto the window.
Evidence files are not inside the backup. They live in IndexedDB and can be large. The pack keeps each file's name, size and SHA-256 so the report stays verifiable, but export the originals separately if you need them.
Clear all local data
Danger zone. This erases every PumaPurple engagement and every evidence file in this browser. Export a backup first.
Type DELETE EVERYTHING to confirm:
⌘/Ctrl + K
Command palette — jump to any view, test, or action
?
Open this help
⌘/Ctrl + S
Save a quick backup
N
New test
/
Focus the search box
Esc
Close drawer / dialog / menu
About PumaPurple
PumaPurple is a lightweight, portable, offline purple-team exercise tracker that runs entirely in your browser.
This tool is provided as-is, for informational and productivity purposes only. It is not professional security advice. All testing decisions, findings, and records are your own.
About PumaWorx
PumaWorx is a suite of offline, single-HTML productivity apps that run entirely in your local browser. The entire suite is a personal, open source vibecoding project.