· 7 min read
Pentest Report Writing with AI, from Raw Notes to Final Report
Turn pentest notes and scanner output into a client-ready report with AI, covering the executive summary, CVSS v4 findings, remediation and retest notes.
The testing is the fun part. The report is what the client pays for, and it usually gets written at the end of the engagement by someone who is tired. This guide shows how to use Odin v1 to turn raw notes, scanner output and described screenshots into a clean, client-ready pentest report, without handing over judgment or client secrets.
What AI is good at in a pentest report, and what it is not
A language model is good at the parts of reporting that are mostly writing: turning terse notes into full sentences, keeping a consistent structure across 30 findings, writing an executive summary a non-technical reader can follow, and drafting remediation advice that matches the stack you describe.
It is not a source of truth. It did not see the target. It cannot confirm that a finding is real, that your severity is right, or that a reproduction step works. Treat every draft as a junior tester's first pass: useful, fast, and in need of review.
Mainstream assistants add a second problem. Paste in "authenticated user can read other tenants' invoices by changing the ID" and some of them start lecturing about unauthorized access instead of writing the finding. Odin v1 answers directly when the context is a report for an authorized engagement, which is the whole job. We cover why that matters in our launch post.
Before anything leaves your machine: redact
Your notes contain client hostnames, internal IPs, usernames, sometimes session tokens or password hashes. Strip them before sending anything to any API.
A simple rule set covers most of it:
- Replace the client's domains with placeholders such as
client.example.com. - Replace internal and external IPs with documentation ranges (
192.0.2.0/24,198.51.100.0/24,203.0.113.0/24) or tokens likeHOST-A. - Replace real usernames with
user1,admin1. - Remove secrets entirely. A finding about an exposed token needs the token's type and location, not its value.
- Keep a local mapping file so you can restore the real values in the final document.
On InterOdin, API prompts and completions are never stored. Only metadata such as token counts, latency and status is kept for billing, and the servers are in Germany. That is a good baseline, but it does not replace redaction. Your contract with the client decides what data may leave the engagement environment, so check it first.
The report structure to aim for
Most client reports share the same skeleton. Give the model this structure explicitly so every draft lands in the same shape:
Each finding block should have: title, severity, CVSS v4 vector, affected assets, description, impact, reproduction steps, evidence, remediation, references.
A prompt template for one finding
Here is a realistic set of raw notes from an authorized web application test (already redacted):
And a prompt that turns it into a finding:
What to expect back: a title along the lines of "Insecure Direct Object Reference in Invoice API Exposes Other Tenants' Data", a description of the broken object-level authorization check, an impact paragraph about cross-tenant disclosure of personal and billing data, numbered steps that use two test accounts in different tenants, and remediation that says to enforce tenant ownership on the server for every object lookup, with a note that switching to random IDs alone is not a fix. References usually include OWASP API Security Top 10 (API1, Broken Object Level Authorization) and CWE-639.
For the vector, expect something like:
with a line per metric explaining why, for example "PR:L because a normal authenticated account is required". Always calculate the final score yourself in the official FIRST CVSS v4.0 calculator and check every metric against what you actually observed. The model can reason about metrics, but the score in your report is your responsibility.
A Python script that drafts a finding from notes
This script reads a notes file, applies a small redaction map, sends it to odin-v1 and writes a Markdown draft. It uses the official OpenAI SDK pointed at the InterOdin base URL (see the OpenAI SDK guide).
Run it per finding: python draft_finding.py notes/finding-17.txt. Print the redacted text to your terminal once before the first real run so you can see exactly what will be sent.
Scanner output and screenshots
Scanner exports are noisy. Instead of pasting a full report, filter it first (only the plugin IDs or templates you confirmed by hand), then ask the model to group related issues. Ten "missing security header" lines usually belong in one low-severity finding with a list of affected hosts, not ten findings.
Odin accepts text only, so images and PDFs cannot be uploaded. That works fine for reporting: describe each screenshot in a line or two in your notes ("screenshot 17: tenant B invoice visible in user1 session, invoice number and address shown"). The model then references the evidence by name, and you place the real, redacted images in the final document yourself.
For large engagements, odin-v1 has a 1,000,000-token context window, so you can pass all your redacted findings at once when you write the executive summary. For quick, repetitive tasks such as normalizing finding titles or reformatting reference lists, odin-flash is faster and cheaper.
Executive summary and remediation roadmap
Once the findings are reviewed, generate the summary from the findings themselves, not from your raw notes:
Then ask for a remediation roadmap that groups fixes by owner (development, infrastructure, identity) and by effort. Clients act on roadmaps far more than on severity tables.
Retest notes
After the fix window, add a short retest block per finding: date, what was retested, result (fixed, partially fixed, not fixed) and evidence. A useful prompt is "Here is the original finding and my retest notes. Write a retest status block of at most 80 words, and flag any mismatch between the original reproduction steps and what I retested." That last part catches retests that quietly tested something different.
Review checklist before delivery
- Every finding was confirmed by a human tester, with evidence.
- Every CVSS score was computed in the official calculator.
- No [NEEDS TESTER INPUT] markers remain.
- Placeholders were mapped back to real values only in the final document.
- Nothing outside the agreed scope appears in the report.
If you automate more of this, for example a script that assembles the full report from finding files, our post on building security tooling with Claude Code on Odin walks through that kind of project. Newer testers building skills in labs may also like CTF practice with an AI coach.
Get started
Create an API key in the console, set it as INTERODIN_API_KEY, and follow the quickstart. Keep every engagement within its written scope and rules of engagement, and within the Acceptable Use Policy.