evidence-vault-chain-of-custody · git:20260913.e13b6b8 · 2026-09-13 · sha256 860249d7f85a8f1e
evidence-vault-chain-of-custody git:20260913.e13b6b8A
Immutable. This exact content is served forever at /api/v1/blob/860249d7f85a8f1e.
--- name: evidence-vault-chain-of-custody description: "Evidence management for security engagements: chain-of-custody records with SHA-256 integrity, the provenance-strict verification gate (a finding is only 'verified' when backed by real tool output, never prose), credential redaction for any outward-facing surface, CVSS-to-severity scoring, and authorized retest workflows with typed probe dispositions. Use when structuring findings/evidence storage for a pentest or bug-bounty engagement, deciding what evidence makes a claim reportable, redacting captured credentials from reports, or re-testing fixed vulnerabilities. Derived from the T3MP3ST platform's evidence vault (Apache-2.0)." category: security triggers: - "evidence vault" - "chain of custody" - "finding verification" - "provenance" - "credential redaction" - "retest finding" - "severity scoring" tools: - file_read - file_glob - file_grep - file_write - file_edit - dir_list - shell_execute --- # Evidence Vault & Chain of Custody Derived from T3MP3ST's `src/evidence/` (Apache-2.0). The core principle: **a claim is only as strong as its provenance. Prose is not evidence.** ## 1. The provenance-strict verification gate A finding may be marked `verified` ONLY when backed by real tool output. The gate is honest by construction — it never invents provenance, and it states why it blocked: - **Tool evidence types** that count: `output`, `command`, `response`, `request`, `log`, `file` — each with non-empty content. A human note or a narrative paragraph is `context`, not proof. - **Zero tool evidence → FAIL** with reason: "no tool-output evidence — provenance-strict requires a finding be backed by real tool output, not prose". - **Severity must be earned:** asserting `critical` or `high` with zero evidence of any kind is an overclaim and fails the gate. - **Typed provenance:** `none` (no evidence at all), `context` (notes only), `tool` (real output). Only `tool` passes. Apply the same gate to your own work: before you report a finding to the operator, list the exact tool receipt (command output, HTTP pair, log line) that backs it. No receipt → report it as a lead, not a confirmed finding. ## 2. Chain-of-custody records Every acquired artifact gets a record with these fields: ``` id, caseId, targetId, name, source, collectedAt, receivedAt, sha256, sizeBytes, collector, transfer, verified, redactedMetadata ``` Rules the record enforces: - `sha256` is computed at acquisition and re-verified on read (`verified` flag) — integrity is checked, not assumed. - `collectedAt` (when the artifact was taken) and `receivedAt` (when the vault accepted it) are separate timestamps; a gap is part of the record. - Duplicate artifact names within one acquisition are rejected — a vault that silently dedups is a vault that loses evidence. - Metadata is redacted at acquisition time (`redactedMetadata`), not later. - Acquisition outcomes are typed: `collected | cancelled | permission-denied | collection-failed`. Permission errors are their own outcome — never retried as if they were transient. ## 3. Credential redaction — secrets never leave the process Captured credentials are the highest-risk data in any engagement: - The outward-facing shape of a credential strips the raw `secret` and replaces it with a boolean `secretCaptured` flag. All non-sensitive metadata (user, target, protocol, source) is kept. - This applies to EVERY outward surface: API responses, reports, prompts to other models, chat output. If the surface can be read by someone else, it gets the redacted shape. - Never "temporarily" include a secret in output with intent to redact later — redaction happens at the boundary, by construction. ## 4. Severity scoring | CVSS | Severity | |---|---| | ≥ 9.0 | critical | | ≥ 7.0 | high | | ≥ 4.0 | medium | | ≥ 0.1 | low | | 0 | info | Severity weights for scoring runs: critical 10, high 7.5, medium 5, low 2.5, info 0. Severity is derived from CVSS or demonstrated impact — never from how exciting the finding feels. ## 5. Authorized retest workflow Re-testing a previously-reported finding after a fix: - Statuses: `fixed | still_vulnerable | unverifiable`. - Each attempt records a probe disposition: `present` (vuln still observable), `absent` (fix confirmed), `inconclusive` (probe could not tell — retryable). - Attempts are bounded (`maxAttempts`), timestamped, and carry the exact tool + arguments used. Provenance is explicit: `authorized-tool-retest`. - `unverifiable` is a real outcome — report it as such instead of guessing. ## 6. OSA-specific wiring - Store evidence under a scratchpad or case directory, never in the repo. - Hash with `sha256sum` `[LOCAL]`; keep the JSONL log format from `offensive-osint` (`run_id`, `ts`, `tool`, `artifact`, `sha256`, `next`). - Findings that fail the gate go to the operator as leads with the reason attached — the gate's refusal text is the report. ## Attribution Derived from [elder-plinius/T3MP3ST](https://github.com/elder-plinius/T3MP3ST) (`src/evidence/index.ts`, `src/evidence/gate.ts`, `src/evidence/retest.ts`), Apache-2.0. Patterns described; no code copied. Part of the offensive skill library — see also `penetration-testing` and `redteam-multi-agent-orchestration`.