Self-hosted · Offline · No telemetry
Turn scanner output into client-ready reports — without your data ever leaving your machine.
Triagely ingests Nmap, Nuclei, and Burp output, deduplicates findings across tools, and generates a branded PDF. It runs entirely on your own box. Nothing phones home.
Works with the tools you already use
- Nmap
- Nuclei
- Burp Suite
Reads their standard output formats — no plugins, no agents. At home in the Kali Linux ecosystem. Nmap, Nuclei, and Burp Suite are trademarks of their respective owners; Triagely is an independent tool and is not affiliated with or endorsed by them.
You do the testing. We kill the reporting.
The engagement is the fun part. The write-up is the tax you pay afterward — copying findings out of four tools, reconciling the ones that overlap, normalizing severities, and formatting it all into something a client will read.
Triagely aggregates the raw output from every tool you already run, collapses duplicate findings into one entry that credits each scanner, and auto-generates the document you'd otherwise hand-write. You review and ship — you don't retype.
-
One normalized schema
Nmap, Nuclei, and Burp output parsed into a single finding model — severity, asset, evidence, CWE/CVE.
-
Cross-tool dedup
The same issue seen by two scanners becomes one finding that keeps every tool's evidence and rating.
-
Report-grade output
A branded PDF with cover, exec summary, findings, and appendix — plus manual findings you add yourself.
How it works
Three steps. Real commands. No lock-in — it reads the files your tools already produce.
-
01
Run your tools
Scan the target however you normally do. Just save machine-readable output.
nmapnmap -sV --script vuln <target> -oX scan.xmlnucleinuclei -u <target> -jsonl -o results.jsonlburp# Burp UI: Target ▸ Site map ▸ right-click host ▸ # "Report selected issues" ▸ XML → burp.xml -
02
Upload the output files
Open the dashboard, create an engagement, and drop in
scan.xml,results.jsonl, andburp.xml. The tool auto-detects each format, parses it, and deduplicates across all of them as you go.upload# or from the CLI, straight to the local API curl -F file=@scan.xml localhost:7442/engagements/<id>/ingest/nmap -
03
Get a deduplicated, branded PDF
Triage the merged findings, mark false positives, add manual findings with evidence, then export. Out comes a client-ready report — your accent color and logo, one clean document.
exportcurl -o report.pdf localhost:7442/engagements/<id>/report.pdf
Quickstart
One container. One port. The full app — API and dashboard.
The image is private — request access and you'll be added, then the commands below just work.
docker run -p 7442:8080 -v "$(pwd)/data:/data" ghcr.io/pentest-reports/pentest-reporter:latest
Then open http://localhost:7442.
The image is pulled from the registry — there's nothing to build. Your database lives at
./data/pentest.db on your disk and survives restarts, upgrades, and re-pulls.
Port already in use? Change only the first number —
-p 9000:8080 — and browse to localhost:9000 instead. The container
always listens on 8080 internally; 7442 is just an uncommon host
default (so it won't fight Burp's proxy, Jenkins, or your dev servers on 8080).
Prefer Compose? Drop this in a docker-compose.yml and run docker compose up:
services:
pentest-reporter:
image: ghcr.io/pentest-reports/pentest-reporter:latest
ports:
- "7442:8080" # change 7442 if the port is taken
volumes:
- ./data:/data
restart: unless-stopped
Why self-hosted matters
You're under NDA. Client findings are some of the most sensitive data you handle. It should never touch someone else's server — and here it doesn't.
Data stays on your machine
Findings and reports are written to a local SQLite file in ./data. There is no cloud account and no shared tenancy.
Nothing phones home
No telemetry, no analytics, no license check. The container needs no outbound network access to do its job.
Works fully offline
Run it on an air-gapped box or inside a client's environment. Pull the image once and it runs disconnected.
You can verify it
Don't take our word for it — watch it. Put it behind a network monitor and see zero outbound connections, or run it fully air-gapped. Its behavior is observable, not a promise.
See it
The dashboard where you triage, and the PDF you hand to the client.
Stop hand-writing reports.
Pull the image, run one command, and generate your next report tonight.