AttackLedger

Nothing counts as tested until it has a receipt.

AttackLedger proves what a security test actually covered. It runs recon and hunting within the program's rules, keeps every test as hash-chained evidence, and has a person sign off each lane. Anyone can verify the report offline.

Authorization

app.client.test
  1. ✓WSTG-ATHZ-01Directory traversal and file inclusion7eafbd2f
  2. ✓WSTG-ATHZ-02Bypass of the authorization schema0853f816
  3. ✓WSTG-ATHZ-03Privilege escalationd99f6940
  4. ✓WSTG-ATHZ-04Insecure direct object references35faa313
Receipt signed by the reviewer after reading the evidence Manifest 8ed282dde205101815ab8ba63a2e41d07fda63838736c1e37a869c9acc27840a
One lane of the sample report, with fictional hosts. Change any evidence entry and the receipt goes void.

“Done” is easy to claim

Scanners, checklists and AI agents all report that the work is finished. Few of them can show which hosts were tested, which checks ran, and what the evidence was. Agents in particular tend to stop early and call it complete.

AttackLedger treats “tested” as something you compute from evidence, not something you declare.

Where coverage goes missingWhat AttackLedger does
  • Hosts found in recon never reach testingEvery in-scope host has a row in the coverage matrix until each lane on it is receipted
  • A checklist is closed with items still openA lane closes only when every item has evidence or a written reason
  • The work changes after it was signed offThe receipt is a hash of the lane; any later change makes it void
  • Nobody can check the report afterwardsThe report carries its own evidence chain and verifies offline

How it works

  1. Record the rules

    Scope rules, rate limit, the research header the program requires, and your authorization. Nothing runs without them.

  2. Run recon

    Subdomains, DNS, live web servers, crawling, archives, JavaScript analysis, and opt-in ports, content, parameter and nuclei scans.

  3. Open lanes

    Each host gets lanes from a methodology pack: bug bounty roles or the OWASP WSTG. Each lane is a checklist.

  4. Collect evidence

    You, or a Claude agent within the lane's rules, attach evidence to each item. Every entry is hash-chained to the one before.

  5. Sign the receipt

    A person reviews the lane and signs. Only a person can close a lane; an agent never can.

  6. Hand over the report

    JSON or HTML with the full chain and every receipt, mapped to controls, verifiable with the Python standard library.

Who it's for

Bug bounty hunters

Know which hosts and checks you have covered on each program, and which are still open, instead of keeping it in your head. The program's scope, header and rate limit are enforced for you.

Pentest firms and red teams

Hand the client evidence of what was tested, not only a list of findings. Each lane carries the reviewer's signature, and the client can check the report without trusting your tools.

Auditors and regulated firms

Check a penetration test against the controls it is meant to satisfy, such as PCI DSS requirement 11.4, DORA threat-led testing or ISO/IEC 27001, and verify the evidence chain yourself.

Guardrails it enforces

  • Fail-closed scope. Unknown hosts are out of scope, exclusions win, and a wildcard does not cover its apex.
  • Research identification on every request. Tools refuse to send traffic to a target without the header or user agent the program asks for.
  • The rate limit is a ceiling. It applies to every step, port scanning included, with no multiplier.
  • No redirects followed. A 3xx is recorded as it is, so nothing wanders off scope.
  • Risky modules are opt-in. Port scans, content discovery, parameter discovery and vulnerability scanning stay off until the policy allows them.
  • Unsafe templates are excluded. No DoS, fuzzing, brute force, default logins or out-of-band callbacks.
  • Secrets are never used. Candidates found in JavaScript are stored masked and hashed, and are never tested.
  • Agents stay read-only. A Claude agent works one lane with GET, HEAD and OPTIONS on that host only, and cannot sign a receipt.

Vulnerability scan on the lab: 8,899 of 8,899 requests carried the research identification.

Content discovery on the lab: peak of 20 requests per second at a limit of 20, over 9,504 requests.

Measured against a local lab target with a raw request logger, not against a live program.

For auditors and reviewers

Each checklist item carries the controls it gives evidence for. The report lists which controls are evidenced, partly evidenced or not covered, per host.

  • PCI DSS 4.0
  • ISO/IEC 27001:2022
  • DORA

The control mappings are indicative and need review against the current text of each standard.

Verifying a report needs no AttackLedger installation, only Python:

$ python3 verify_report.py sample-report.json \
    --tsa-root digicert-trusted-root-g4.pem
AttackLedger report: Client web app (Web application pentest (OWASP WSTG) 0.1)
  5 receipted lanes, 43 evidence entries

  PASS  Report body hash
  PASS  Evidence chain
  PASS  Lane receipts
  PASS  Receipt signatures
  PASS  Receipt timestamps

Verified.

Sample report

A web application pentest on two fictional hosts, app.client.test and api.client.test, worked through the OWASP WSTG pack: 6 lanes opened, 5 receipted, 43 evidence entries. All data in it is sample data.

The read-only demo is the AttackLedger app itself, loaded with the same kind of sample data: recon from a real run against a local lab, lanes, evidence, receipts and reports.

Open the sample report

Each receipt in it is signed by the demo reviewer's key and timestamped by DigiCert's public timestamp service. To check it yourself, take sample-report.json, verify_report.py and DigiCert's root certificate, digicert-trusted-root-g4.pem (SHA-256 fingerprint 552F7BDC…0AC89988, also in your operating system's root store), and run the command above.

Where it's going

More and more security testing will be done by AI agents. That makes one question more important: who tested what, and can anyone check it?

The aim is a ledger for offensive security: a record of each test that the client, the auditor or the regulator can verify independently, whoever or whatever did the testing.

  1. Agents test They work inside the lane's rules and attach what they observed.
  2. People sign They review the evidence first. Only a person closes a lane.
  3. Auditors verify Offline, without trusting the tool or the tester.

Built: people with roles, separation of duties, receipts signed with a key held in the reviewer's browser, and RFC 3161 timestamps from an authority you choose. Later: evidence import from tools such as Caido, and compliance packs reviewed against the current standards.

Licence and status

AttackLedger is open source under the AGPL-3.0, with a commercial licence for teams that cannot use AGPL software. The current version is a preview: recon is complete, and agent-assisted hunting has been tested on a local lab. The source code will be published here.

AttackLedger is for authorized testing only: programs whose scope you are in, or systems you own or have written permission to test.

Questions, early access or a commercial licence:

murat@attackledger.com