After every API security test, record the scope, date, environment, accounts and roles used, mode, tools and versions, coverage, findings with evidence, what was not tested, owner, fixes and the retest date. With those twelve fields, someone else can judge the result a year later.
Why the record matters
A test result without context is hard to use. A buyer asks "did you test your API?" and the honest answer depends on what was tested, as whom, and how recently. An engineer asks "was this endpoint covered?" and nobody knows. NIST SP 800-115, the technical guide to security testing and assessment, frames testing as something you plan, conduct, analyze and then use to develop mitigation strategies. A record is how the analysis and mitigation steps get anything to work with.
The twelve fields
| Field | What to write |
|---|---|
| Scope | Hosts, versions and paths tested, and anything excluded |
| Date and window | Start and end times, in one stated time zone |
| Environment | Production, staging or a seeded test environment |
| Accounts and roles | Which users and roles were used, and whether sessions stayed valid |
| Mode | Passive or active, write methods allowed or not, rate ceiling |
| Tools and versions | Scanner, version, rule configuration, manual methods used |
| Coverage | Operations tested compared with operations known |
| Findings | Each with request, response, affected operation and severity |
| Not tested | Everything skipped, and why |
| Owner | The person accountable for the test and for each finding |
| Fixes | Ticket links, fix dates, and who verified them |
| Retest | The date the fixes were confirmed, or the scheduled date |
Why each one earns its place
Accounts and roles. Authorization results mean nothing without them. OWASP's guidance for object level testing is two accounts, and function level testing needs lower and higher roles.
Mode. A passive run and an active run are different tests. Record the difference so nobody reads one as the other.
Coverage. OWASP's inventory guidance recommends keeping each host's environment, access level and version listed. Coverage is how many of those you actually tested.
Not tested. This is the most skipped field and the one that stops a false sense of safety.
Retest. A finding is only closed when someone has checked the fix. Write the date.
Keep it light
You do not need a long report for every run. One page per test, in a consistent format, filed where the team can find it. Store the raw scanner output next to it. Name files by date and target.
Redact before sharing
If you share results with a customer or auditor, remove credentials, tokens, real user data and internal hostnames you would not publish. Share a summary and offer detail under agreement, rather than sending raw requests.
Where Safeguard fits
Safeguard's compliance and evidence automation can help collect and date records like these alongside other engineering evidence, and its framework mapping view shows how evidence lines up with control sets. It does not replace the human judgment in the findings and not-tested fields.
Worked example: one test record, filled in
To make the twelve fields concrete, here is a record for an imaginary test of a shipping API. It is short on purpose. Notice that it fits on a page.
| Field | Entry |
|---|---|
| Scope | shipping-api staging, versions v1 and v2, all routes in the spec plus three found from traffic. Excluded: carrier sandbox host |
| Date and window | 14 October 2026, 09:00 to 11:30, UTC |
| Environment | Staging, reseeded with synthetic data before the run |
| Accounts and roles | shipper_a, shipper_b, warehouse_staff, admin, anonymous. Session canary passed throughout |
| Mode | Active, write methods allowed on seeded objects, ceiling 15 requests per second |
| Tools and versions | Open-source API scanner at a stated version with a saved config file, plus 90 minutes of manual authorization testing |
| Coverage | 87 of 91 known operations. Four skipped because they send real emails, noted |
| Findings | 5: one object access flaw on v1, one missing role check on a label reprint route, one excessive field in the tracking response, two low header items. Each with request and response saved |
| Not tested | Business rules on refunds, WebSocket tracking feed, partner callback signing |
| Owner | Named security lead, with a named engineer per finding |
| Fixes | Five tickets linked, due dates set, four fixed within two weeks |
| Retest | 28 October 2026 for the four fixes, the remaining one scheduled with the next release |
How this record gets used
By a developer. An engineer picks up the label reprint ticket. The record tells them which account triggered it, which environment, and where the raw request is saved. They reproduce it in minutes.
By a buyer review. A customer asks about API testing. The team shares a redacted version: scope, date, accounts, mode, findings count and fix status, without hostnames or raw requests.
By an auditor. The record shows a dated test, a tracked list of findings and a retest date. It is evidence that a testing activity happens on a schedule. It is not a certification, and it should not be described as one.
By next quarter's tester. They see exactly what was not tested, and put it first. The WebSocket feed and partner callbacks become the starting point for the next round.
Common ways records go wrong
| Problem | Effect | Fix |
|---|---|---|
| No accounts listed | Nobody can tell whether authorization was tested | Make accounts a required field |
| Mode missing | Passive and active runs look the same | Add one line for mode and methods |
| Not-tested left blank | False sense of completeness | Write "none known" only if you have checked |
| No retest date | Findings stay open forever | Set the date when the ticket is created |
| Raw secrets in the file | A leak waiting to happen | Store references to the secrets manager, redact tokens |
Storage and naming
Keep the records in one folder, named by date and target, for example shipping-api, then the date. Put the raw scanner output next to the one-page record. A short index file lists every test, its date and its status, so anyone can see the cadence at a glance.
Teams that do this for four quarters usually find the habit has side benefits: the same table becomes the agenda for the planning meeting before the next test.
Making the record easy to fill in
A record nobody fills in is worse than none. A few habits keep the cost low.
- Start from a template. Keep the twelve fields as a blank file in the repository, and copy it at the start of every test.
- Fill it in as you go. Write scope and accounts before the run, and findings and gaps right after. Waiting a week means forgetting what was skipped.
- Link instead of paste. Point to raw output, tickets and the config file. Pasting long output makes the record unreadable.
- Assign one owner. The person who ran the test fills in the record, and a second person reviews it for gaps.
- Keep a changelog of the template. If you add a field, note the date, so older records are not judged by newer standards.
- Review the index monthly. Check that every test has a retest date and that overdue retests are chased.
Over a year, these records tell a story about how your API security improved, which areas you tested the most, and where gaps remain. That story is far more convincing to a customer than any single clean report.
Try it yourself
Open the demo and look at how evidence is tied to controls. Think about which of the twelve fields would attach to each control in your own program.
Click through it at your own pace, or open it full screen.
Quick check
Is a scanner's exported report enough as a record?
It is a start, but it rarely holds scope decisions, accounts, the not-tested list or fix verification. Add those in a short cover page.
How long should I keep the records?
Follow your own retention policy and any contract terms. Keep at least enough history to show the testing schedule over your audit or review period.
Does keeping these records mean we are compliant with a framework?
No. They are evidence that testing took place and was followed up. Whether that satisfies a particular control is a decision for your assessor and your own control owners.
Sources
- NIST SP 800-115: Technical Guide to Information Security Testing and Assessment
- OWASP API9:2023 Improper Inventory Management
- OWASP WSTG: API broken object level authorization
Last reviewed: 19 October 2026.