# THEORY — Chain of Custody for Pentest Evidence

## Why chain of custody matters

A pentest produces evidence. Evidence has two properties that
matter legally:

1. **Integrity** — the evidence has not been modified since it was
   collected.
2. **Provenance** — the evidence's path from creation to current
   custodian is documented.

Together they answer: "is this report telling me what was actually
found, or has someone edited it after the fact?"

The downstream consumers of pentest evidence vary by engagement:

- **Customer's internal audit team** — needs to file the report
  for compliance evidence (SOC2, ISO 27001, PCI DSS audit).
- **Legal counsel** — needs the evidence for breach
  notification, insurance claim, or litigation contexts.
- **Outside SOC reviewing the activity** — needs to confirm that
  alerts they raised during the engagement match authorized
  testing.
- **Future readers of the same customer's engagement history** —
  need to know what was tested when, to make scope decisions for
  the next engagement.

Each consumer asks variations of "show me the proof." The
chain-of-custody artifact this skill produces is that proof.

## NIST SP 800-86 evidence-handling principles

NIST Special Publication 800-86 (Guide to Integrating Forensic
Techniques into Incident Response) establishes the principles
this skill follows:

- Acquire evidence using techniques that preserve the original
  state.
- Document everything — who, what, when, where, how.
- Use cryptographic hashing to detect any modification after
  acquisition.
- Limit access to evidence to a documented chain of custody.

The pentest case isn't a forensic incident, but the same
principles apply: the evidence we produce will be examined by
parties we don't fully control, and they need objective grounds
to trust it.

## SHA-256 vs SHA-3 vs SHA-512

The skill uses SHA-256. Reasons:

- **Universally available.** Python's `hashlib`, Linux's
  `sha256sum`, macOS's `shasum`, Windows's `Get-FileHash`. No
  party verifying the manifest needs to install anything special.
- **No known practical preimage attacks** as of 2026. Collision
  attacks on SHA-256 have been theorized but not demonstrated.
- **Output size (64 hex chars) is human-tractable** for spot
  checks.

SHA-3 is fine — academically preferred for new designs — but
tooling is less universal. SHA-512 is fine too — slightly slower,
larger output. For evidence-integrity purposes, SHA-256 is
sufficient and the most portable choice. If your customer's policy
requires SHA-512, the skill could be extended to emit both.

MD5 and SHA-1 are NOT acceptable. Both have practical collision
attacks. Don't use them for evidence integrity even if old tooling
defaults to them.

## GPG detached signatures

A GPG detached signature is a separate file (typically `.asc` or
`.sig`) that contains a cryptographic signature over the contents
of the original file, made with the signer's private key. Anyone
with the signer's public key can verify:

- The signature was made by the holder of the private key.
- The signed content hasn't been modified since signing.

Detached signatures are preferred over inline signatures because
the original file remains unchanged — easier to feed to tools that
expect the original format.

The skill produces `manifest.sha256.asc` alongside the
`manifest.sha256`. Verification flow:

1. `gpg --verify manifest.sha256.asc manifest.sha256` — confirms
   the manifest is signed by the claimed signer.
2. `sha256sum -c manifest.sha256` — confirms the manifest's
   contents match the on-disk files.

Both checks together: the signer attests that the manifest is
correct, AND the manifest is currently correct against the
archive.

## Archive format choices

The skill uses gzip-compressed tar (`.tar.gz`) for the optional
portable archive. Comparison:

| Format | Tooling | Compression | Notes |
|---|---|---|---|
| `.tar.gz` | universal (Linux/macOS/Windows-WSL) | Good | Preserves Unix permissions, mtimes |
| `.zip` | universal (incl. Windows native) | Good | Loses some Unix metadata; password-protect is weak |
| WORM (Write-Once Read-Many) media | requires WORM library | n/a | Strongest integrity claim; expensive |

Tar.gz is the practical choice. WORM is the strongest claim but
operationally rare outside specialized forensic shops. The
manifest provides equivalent integrity guarantees without the
operational burden.

## Retention horizons per jurisdiction

How long to keep pentest evidence depends on the jurisdiction and
the customer's regulatory posture. Common defaults:

| Driver | Typical retention |
|---|---|
| Statute of limitations on unauthorized-access offences (US) | 5 years |
| Statute of limitations (UK, CMA offences) | 6 years |
| SOC2 audit evidence | 7 years |
| ISO 27001 audit evidence | 5 years |
| PCI DSS evidence | 1-3 years (varies by control) |
| HIPAA breach evidence | 6 years from creation or last effective date |
| Customer-contractual retention | varies — read the engagement contract |

The skill doesn't enforce retention — that's a storage-policy
concern. The skill ensures the evidence is portable and verifiable
for whatever retention period applies.

## Out-of-tree path detection

A finding that references a file at `/home/tester/notes.md` is a
chain-of-custody problem: when the engagement archive is moved to
the customer's storage, that file won't come along. The finding
becomes uncheckable.

The skill scans `findings/*.json` for path-shaped string values in
the `evidence` dicts and flags any absolute path that isn't within
the engagement directory tree. The remediation is to copy the
referenced file INTO the engagement tree, OR change the finding to
not reference the out-of-tree path.

## When the customer disputes the archive

Two failure modes:

### "The archive is incomplete"

Customer claims they didn't get all the evidence. Resolution:

1. Run this skill against the archive directory; the report lists
   every file with its hash.
2. Compare the list against the customer's expected file list.
3. If files are missing from the archive, restore from the
   tester's working copy and re-archive.
4. If the customer's expected list includes files that were never
   in scope, document that in the resolution communication.

### "The archive has been modified"

Customer claims the evidence doesn't match what they saw during
the engagement. Resolution:

1. Run `sha256sum -c manifest.sha256` against the archive
   directory. If output is "OK," the archive is internally
   consistent.
2. If the customer's claim is that the EVIDENCE itself was
   manipulated (not the archive), compare against the daily
   snapshots taken during the engagement (if available).
3. If no daily snapshots were taken, the integrity claim depends
   on the original manifest signature and any external retention
   timestamps (e.g. WORM storage, email of the manifest at
   engagement close).

The skill's daily-snapshot pattern (see PLAYBOOK.md) is the cheap
preventive measure for this dispute class.

## Why the manifest is in standard sha256sum format

The skill could emit a custom JSON manifest. The sha256sum format
is preferred because:

- Standard Unix tooling (`sha256sum -c`) verifies it without any
  custom code.
- A customer or legal counsel can verify the manifest 10 years
  from now even if this skill no longer exists.
- The format is line-oriented; diffs are readable.

The standard format is one line per file: 64-hex-char digest,
exactly two spaces, then the file's relative path. Both Linux's
`sha256sum` and macOS's `shasum -a 256` produce and verify this
form.
