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.

  1. 01

    Run your tools

    Scan the target however you normally do. Just save machine-readable output.

    nmap
    nmap -sV --script vuln <target> -oX scan.xml
    nuclei
    nuclei -u <target> -jsonl -o results.jsonl
    burp
    # Burp UI: Target ▸ Site map ▸ right-click host ▸
    #          "Report selected issues" ▸ XML  →  burp.xml
  2. 02

    Upload the output files

    Open the dashboard, create an engagement, and drop in scan.xml, results.jsonl, and burp.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 [email protected] localhost:7442/engagements/<id>/ingest/nmap
  3. 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.

    export
    curl -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
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:

docker-compose.yml
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
RuntimeDocker or Podman
Port7442 (remappable)
NetworkNone required
Data./data (local)

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.

Triagely dashboard — findings deduplicated across Nmap, Nuclei, and Burp, grouped by severity
Findings dashboard — grouped by severity, showing which tools confirmed each issue.
Client-ready PDF report — cover page and executive summary with severity breakdown
The exported PDF — cover, executive summary, findings, and appendix.

Stop hand-writing reports.

Pull the image, run one command, and generate your next report tonight.