@intentsolutionsio/penetration-tester 2.0.0 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/.claude-plugin/plugin.json +8 -3
  2. package/README.md +8 -0
  3. package/commands/pentest.md +5 -0
  4. package/package.json +8 -3
  5. package/skills/analyzing-tls-config/SKILL.md +221 -0
  6. package/skills/analyzing-tls-config/references/AUTHORIZATION.md +133 -0
  7. package/skills/analyzing-tls-config/references/PLAYBOOK.md +267 -0
  8. package/skills/analyzing-tls-config/references/THEORY.md +128 -0
  9. package/skills/analyzing-tls-config/scripts/analyze_tls.py +415 -0
  10. package/skills/auditing-cors-policy/SKILL.md +186 -0
  11. package/skills/auditing-cors-policy/references/PLAYBOOK.md +220 -0
  12. package/skills/auditing-cors-policy/references/THEORY.md +142 -0
  13. package/skills/auditing-cors-policy/scripts/audit_cors.py +350 -0
  14. package/skills/auditing-npm-dependencies/SKILL.md +254 -0
  15. package/skills/auditing-npm-dependencies/references/PLAYBOOK.md +175 -0
  16. package/skills/auditing-npm-dependencies/references/THEORY.md +122 -0
  17. package/skills/auditing-npm-dependencies/scripts/audit_npm.py +408 -0
  18. package/skills/auditing-python-dependencies/SKILL.md +251 -0
  19. package/skills/auditing-python-dependencies/references/PLAYBOOK.md +193 -0
  20. package/skills/auditing-python-dependencies/references/THEORY.md +122 -0
  21. package/skills/auditing-python-dependencies/scripts/audit_python.py +459 -0
  22. package/skills/checking-http-security-headers/SKILL.md +176 -0
  23. package/skills/checking-http-security-headers/references/PLAYBOOK.md +212 -0
  24. package/skills/checking-http-security-headers/references/THEORY.md +137 -0
  25. package/skills/checking-http-security-headers/scripts/check_headers.py +362 -0
  26. package/skills/checking-license-compliance/SKILL.md +225 -0
  27. package/skills/checking-license-compliance/references/PLAYBOOK.md +161 -0
  28. package/skills/checking-license-compliance/references/THEORY.md +152 -0
  29. package/skills/checking-license-compliance/scripts/check_licenses.py +461 -0
  30. package/skills/composing-vulnerability-report/SKILL.md +212 -0
  31. package/skills/composing-vulnerability-report/references/PLAYBOOK.md +180 -0
  32. package/skills/composing-vulnerability-report/references/THEORY.md +178 -0
  33. package/skills/composing-vulnerability-report/scripts/compose_report.py +396 -0
  34. package/skills/confirming-pentest-authorization/SKILL.md +247 -0
  35. package/skills/confirming-pentest-authorization/references/PLAYBOOK.md +189 -0
  36. package/skills/confirming-pentest-authorization/references/THEORY.md +167 -0
  37. package/skills/confirming-pentest-authorization/scripts/check_authorization.py +457 -0
  38. package/skills/defining-pentest-scope/SKILL.md +227 -0
  39. package/skills/defining-pentest-scope/references/PLAYBOOK.md +238 -0
  40. package/skills/defining-pentest-scope/references/THEORY.md +170 -0
  41. package/skills/defining-pentest-scope/scripts/define_scope.py +472 -0
  42. package/skills/detecting-command-injection-patterns/SKILL.md +144 -0
  43. package/skills/detecting-command-injection-patterns/references/PLAYBOOK.md +302 -0
  44. package/skills/detecting-command-injection-patterns/references/THEORY.md +206 -0
  45. package/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py +290 -0
  46. package/skills/detecting-debug-endpoints/SKILL.md +207 -0
  47. package/skills/detecting-debug-endpoints/references/PLAYBOOK.md +402 -0
  48. package/skills/detecting-debug-endpoints/references/THEORY.md +218 -0
  49. package/skills/detecting-debug-endpoints/scripts/probe_debug.py +518 -0
  50. package/skills/detecting-directory-listing/SKILL.md +206 -0
  51. package/skills/detecting-directory-listing/references/PLAYBOOK.md +277 -0
  52. package/skills/detecting-directory-listing/references/THEORY.md +203 -0
  53. package/skills/detecting-directory-listing/scripts/probe_directory_listing.py +180 -0
  54. package/skills/detecting-eval-exec-usage/SKILL.md +128 -0
  55. package/skills/detecting-eval-exec-usage/references/PLAYBOOK.md +306 -0
  56. package/skills/detecting-eval-exec-usage/references/THEORY.md +159 -0
  57. package/skills/detecting-eval-exec-usage/scripts/scan_eval.py +223 -0
  58. package/skills/detecting-exposed-secrets-files/SKILL.md +179 -0
  59. package/skills/detecting-exposed-secrets-files/references/PLAYBOOK.md +274 -0
  60. package/skills/detecting-exposed-secrets-files/references/THEORY.md +174 -0
  61. package/skills/detecting-exposed-secrets-files/scripts/probe_secrets.py +207 -0
  62. package/skills/detecting-insecure-deserialization/SKILL.md +148 -0
  63. package/skills/detecting-insecure-deserialization/references/PLAYBOOK.md +333 -0
  64. package/skills/detecting-insecure-deserialization/references/THEORY.md +199 -0
  65. package/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py +250 -0
  66. package/skills/detecting-sql-injection-patterns/SKILL.md +161 -0
  67. package/skills/detecting-sql-injection-patterns/references/PLAYBOOK.md +317 -0
  68. package/skills/detecting-sql-injection-patterns/references/THEORY.md +261 -0
  69. package/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py +354 -0
  70. package/skills/detecting-ssl-cert-issues/SKILL.md +182 -0
  71. package/skills/detecting-ssl-cert-issues/references/PLAYBOOK.md +203 -0
  72. package/skills/detecting-ssl-cert-issues/references/THEORY.md +133 -0
  73. package/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py +481 -0
  74. package/skills/detecting-weak-cryptography/SKILL.md +147 -0
  75. package/skills/detecting-weak-cryptography/references/PLAYBOOK.md +466 -0
  76. package/skills/detecting-weak-cryptography/references/THEORY.md +194 -0
  77. package/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py +417 -0
  78. package/skills/fingerprinting-server-software/SKILL.md +191 -0
  79. package/skills/fingerprinting-server-software/references/PLAYBOOK.md +337 -0
  80. package/skills/fingerprinting-server-software/references/THEORY.md +183 -0
  81. package/skills/fingerprinting-server-software/scripts/fingerprint_server.py +347 -0
  82. package/skills/generating-executive-summary/SKILL.md +261 -0
  83. package/skills/generating-executive-summary/references/PLAYBOOK.md +201 -0
  84. package/skills/generating-executive-summary/references/THEORY.md +195 -0
  85. package/skills/generating-executive-summary/scripts/exec_summary.py +538 -0
  86. package/skills/mapping-findings-to-owasp-top10/SKILL.md +235 -0
  87. package/skills/mapping-findings-to-owasp-top10/references/PLAYBOOK.md +193 -0
  88. package/skills/mapping-findings-to-owasp-top10/references/THEORY.md +160 -0
  89. package/skills/mapping-findings-to-owasp-top10/scripts/map_owasp.py +540 -0
  90. package/skills/performing-penetration-testing/SKILL.md +282 -190
  91. package/skills/performing-penetration-testing/references/OWASP_TOP_10.md +22 -0
  92. package/skills/performing-penetration-testing/references/REMEDIATION_PLAYBOOK.md +46 -0
  93. package/skills/performing-penetration-testing/references/SECURITY_HEADERS.md +41 -0
  94. package/skills/performing-penetration-testing/scripts/code_security_scanner.py +144 -79
  95. package/skills/performing-penetration-testing/scripts/dependency_auditor.py +116 -93
  96. package/skills/performing-penetration-testing/scripts/security_scanner.py +574 -446
  97. package/skills/probing-dangerous-http-methods/SKILL.md +182 -0
  98. package/skills/probing-dangerous-http-methods/references/PLAYBOOK.md +234 -0
  99. package/skills/probing-dangerous-http-methods/references/THEORY.md +145 -0
  100. package/skills/probing-dangerous-http-methods/scripts/probe_methods.py +263 -0
  101. package/skills/recording-pentest-engagement/SKILL.md +253 -0
  102. package/skills/recording-pentest-engagement/references/PLAYBOOK.md +203 -0
  103. package/skills/recording-pentest-engagement/references/THEORY.md +195 -0
  104. package/skills/recording-pentest-engagement/scripts/record_engagement.py +461 -0
  105. package/skills/scanning-for-hardcoded-secrets/SKILL.md +215 -0
  106. package/skills/scanning-for-hardcoded-secrets/references/PLAYBOOK.md +325 -0
  107. package/skills/scanning-for-hardcoded-secrets/references/THEORY.md +175 -0
  108. package/skills/scanning-for-hardcoded-secrets/scripts/scan_secrets.py +395 -0
  109. package/skills/tracing-transitive-vulnerabilities/SKILL.md +235 -0
  110. package/skills/tracing-transitive-vulnerabilities/references/PLAYBOOK.md +233 -0
  111. package/skills/tracing-transitive-vulnerabilities/references/THEORY.md +138 -0
  112. package/skills/tracing-transitive-vulnerabilities/scripts/trace_vulns.py +484 -0
@@ -0,0 +1,203 @@
1
+ # PLAYBOOK — Recording, Closeout, and Long-Term Storage
2
+
3
+ ## Recommended engagement directory layout
4
+
5
+ ```
6
+ engagements/<client>-<year>-<quarter>/
7
+ ├── roe.yaml # signed ROE
8
+ ├── allowed-authorizers # signer allowlist
9
+ ├── roe.amendments/
10
+ │ └── amendment-NNN-<date>.yaml
11
+ ├── scope/
12
+ │ ├── allowed-ips.txt # produced by defining-pentest-scope
13
+ │ ├── normalized-targets.json
14
+ │ └── scope-report.md
15
+ ├── findings/
16
+ │ ├── 2026-06-05-cluster1-tls.json # one file per scan session
17
+ │ ├── 2026-06-05-cluster1-cors.json
18
+ │ ├── 2026-06-07-cluster3-secrets.json
19
+ │ └── ...
20
+ ├── evidence/
21
+ │ ├── screenshots/ # PNG / JPG of vulnerable pages
22
+ │ ├── tool-logs/ # raw nmap, Burp, custom tool logs
23
+ │ └── raw-scan-output/ # other raw artifacts
24
+ ├── reports/
25
+ │ ├── vulnerability-report.md # produced by composing-vulnerability-report
26
+ │ ├── owasp-mapping.json # produced by mapping-findings-to-owasp-top10
27
+ │ └── executive-summary.md # produced by generating-executive-summary
28
+ ├── manifest.sha256 # produced by THIS skill
29
+ ├── manifest.sha256.asc # optional GPG signature
30
+ └── chain-of-custody.md # this skill's output report
31
+ ```
32
+
33
+ ## Daily-snapshot cron pattern
34
+
35
+ For long engagements (red-team, multi-month), build a daily
36
+ snapshot trail:
37
+
38
+ ```bash
39
+ #!/usr/bin/env bash
40
+ # cron: 0 23 * * * /opt/pentest/daily-snapshot.sh acme-2026-q2
41
+ ENGAGEMENT="$1"
42
+ ROOT="engagements/${ENGAGEMENT}"
43
+ DATE=$(date +%Y%m%d)
44
+ python3 plugins/security/penetration-tester/skills/recording-pentest-engagement/scripts/record_engagement.py \
45
+ "$ROOT" \
46
+ --manifest "$ROOT/snapshots/manifest-$DATE.sha256" \
47
+ --sign \
48
+ --output "$ROOT/snapshots/snapshot-$DATE.md"
49
+ ```
50
+
51
+ Daily snapshots give you a time-series of the engagement's
52
+ state. If a dispute arises about what was found on a specific
53
+ date, the daily snapshot from that date is the authoritative
54
+ answer.
55
+
56
+ ## Customer-handoff protocol
57
+
58
+ End of engagement:
59
+
60
+ 1. Run the final manifest + signing + archive:
61
+
62
+ ```bash
63
+ python3 ./scripts/record_engagement.py engagements/acme-2026-q2/ \
64
+ --sign --signer your-key-id \
65
+ --tar engagements/archives/acme-2026-q2.tar.gz \
66
+ --output engagements/acme-2026-q2/chain-of-custody.md
67
+ ```
68
+
69
+ 2. Verify the archive end-to-end:
70
+
71
+ ```bash
72
+ cd /tmp/verify
73
+ tar xzf .../acme-2026-q2.tar.gz
74
+ cd acme-2026-q2
75
+ sha256sum -c manifest.sha256 # should print "OK" for every file
76
+ gpg --verify manifest.sha256.asc manifest.sha256
77
+ ```
78
+
79
+ 3. Hand to the customer's documented evidence-receipt contact.
80
+ Get a written acknowledgment of receipt.
81
+
82
+ 4. Archive your own copy in long-term storage (see below).
83
+
84
+ ## Dispute-resolution playbook
85
+
86
+ ### "The customer says the archive is missing files"
87
+
88
+ 1. Run the skill against the archive (current state).
89
+ 2. Run the skill against your tester working copy (current
90
+ state).
91
+ 3. Diff the two file lists. Anything in the tester copy but not
92
+ in the archive is a candidate addition.
93
+ 4. Decide: was the file in scope? In-scope evidence: re-archive
94
+ with addition. Out-of-scope: explain why it wasn't included.
95
+
96
+ ### "The customer says the evidence was modified"
97
+
98
+ 1. Verify the existing manifest: `sha256sum -c manifest.sha256`.
99
+ If OK, archive is internally consistent.
100
+ 2. Verify the GPG signature: `gpg --verify manifest.sha256.asc
101
+ manifest.sha256`. If OK, the manifest is attestably the one
102
+ you produced.
103
+ 3. If both checks pass, the evidence in the archive matches what
104
+ you produced at engagement close. The dispute is about the
105
+ evidence itself, not the archive integrity.
106
+
107
+ ### "The customer says the tester accessed an unauthorized system"
108
+
109
+ 1. Locate the relevant finding(s) referencing the system in the
110
+ archive.
111
+ 2. Cross-reference against `scope/normalized-targets.json` and
112
+ `roe.yaml`.
113
+ 3. If the system was in scope at the engagement time, present
114
+ the cross-reference.
115
+ 4. If the system was NOT in scope, the dispute is about whether
116
+ the access was unauthorized. The tester's own working logs
117
+ (often raw tool output in `evidence/tool-logs/`) may contain
118
+ forensic details about how the access happened.
119
+
120
+ ## Long-term storage patterns
121
+
122
+ | Storage | Pros | Cons |
123
+ |---|---|---|
124
+ | Encrypted S3 bucket with object-lock | Cheap, retention-policy enforceable | Vendor lock-in; cost over decades |
125
+ | Encrypted USB drive in fireproof safe | Air-gapped, simple | Physical loss / damage risk |
126
+ | On-prem NAS with versioned snapshots | Self-controlled | Operational burden, hardware refresh |
127
+ | Cloud + on-prem (both) | Best of both | 2x cost |
128
+
129
+ For pentest evidence with potential litigation exposure, the
130
+ S3-with-object-lock pattern is popular: tier 1 is S3 Glacier with
131
+ 6-year retention lock, tier 2 is local encrypted backup.
132
+
133
+ ## Access control over retained archives
134
+
135
+ Define who can read the archive at retrieval time:
136
+
137
+ - Engagement lead (the tester)
138
+ - Customer authorization recipient (original ROE signer)
139
+ - Legal counsel for either party
140
+ - External auditors (with separate written authorization)
141
+
142
+ Access logs themselves are evidence — log every retrieval of an
143
+ archived engagement with timestamp + retrieving party. Some
144
+ storage systems do this automatically; others require explicit
145
+ audit configuration.
146
+
147
+ ## Encryption of the archive
148
+
149
+ For sensitive engagements (financial services, healthcare,
150
+ defense), encrypt the archive at rest:
151
+
152
+ ```bash
153
+ # After archive creation
154
+ gpg --encrypt --recipient archive-encryption-key \
155
+ --output acme-2026-q2.tar.gz.gpg acme-2026-q2.tar.gz
156
+ # Securely wipe the unencrypted copy
157
+ shred -u acme-2026-q2.tar.gz
158
+ ```
159
+
160
+ The encryption recipient should be a key managed by your firm's
161
+ key-custody process, NOT the tester's individual GPG identity.
162
+ The tester may not be reachable in 7 years; the firm's key
163
+ custody process should be.
164
+
165
+ ## Common closeout mistakes
166
+
167
+ | Mistake | Consequence | Fix |
168
+ |---|---|---|
169
+ | Forgot to manifest screenshots | Customer can't verify screenshot integrity | Re-run skill, re-sign manifest |
170
+ | Manifest signed by tester's personal key | Key unavailable years later | Sign with firm-managed identity |
171
+ | Findings reference paths in tester's home dir | Customer can't open the linked file | Copy files into engagement tree before archiving |
172
+ | Archive on tester's laptop only | Single point of failure | Replicate to long-term storage immediately |
173
+ | No daily snapshots during long engagement | Disputes about specific-date state are uncheckable | Daily snapshot cron |
174
+ | Manifest emitted but never signed | Integrity provable; provenance not | Add `--sign` to closeout command |
175
+
176
+ ## Sample closeout script
177
+
178
+ ```bash
179
+ #!/usr/bin/env bash
180
+ # closeout.sh — run at end of engagement
181
+ set -euo pipefail
182
+ ENGAGEMENT="${1:?engagement name required}"
183
+ ROOT="engagements/${ENGAGEMENT}"
184
+ ARCHIVE_DIR="engagements/archives"
185
+
186
+ mkdir -p "$ARCHIVE_DIR"
187
+
188
+ python3 plugins/security/penetration-tester/skills/recording-pentest-engagement/scripts/record_engagement.py \
189
+ "$ROOT" \
190
+ --sign --signer "firm-pentest-2026" \
191
+ --tar "$ARCHIVE_DIR/${ENGAGEMENT}.tar.gz" \
192
+ --output "$ROOT/chain-of-custody.md" \
193
+ --format markdown
194
+
195
+ # Verify the archive end-to-end
196
+ tmpdir=$(mktemp -d)
197
+ tar xzf "$ARCHIVE_DIR/${ENGAGEMENT}.tar.gz" -C "$tmpdir"
198
+ cd "$tmpdir/${ENGAGEMENT}"
199
+ sha256sum -c manifest.sha256 || { echo "MANIFEST CHECK FAILED"; exit 1; }
200
+ gpg --verify manifest.sha256.asc manifest.sha256 || { echo "SIGNATURE CHECK FAILED"; exit 1; }
201
+
202
+ echo "Closeout complete: $ARCHIVE_DIR/${ENGAGEMENT}.tar.gz"
203
+ ```
@@ -0,0 +1,195 @@
1
+ # THEORY — Chain of Custody for Pentest Evidence
2
+
3
+ ## Why chain of custody matters
4
+
5
+ A pentest produces evidence. Evidence has two properties that
6
+ matter legally:
7
+
8
+ 1. **Integrity** — the evidence has not been modified since it was
9
+ collected.
10
+ 2. **Provenance** — the evidence's path from creation to current
11
+ custodian is documented.
12
+
13
+ Together they answer: "is this report telling me what was actually
14
+ found, or has someone edited it after the fact?"
15
+
16
+ The downstream consumers of pentest evidence vary by engagement:
17
+
18
+ - **Customer's internal audit team** — needs to file the report
19
+ for compliance evidence (SOC2, ISO 27001, PCI DSS audit).
20
+ - **Legal counsel** — needs the evidence for breach
21
+ notification, insurance claim, or litigation contexts.
22
+ - **Outside SOC reviewing the activity** — needs to confirm that
23
+ alerts they raised during the engagement match authorized
24
+ testing.
25
+ - **Future readers of the same customer's engagement history** —
26
+ need to know what was tested when, to make scope decisions for
27
+ the next engagement.
28
+
29
+ Each consumer asks variations of "show me the proof." The
30
+ chain-of-custody artifact this skill produces is that proof.
31
+
32
+ ## NIST SP 800-86 evidence-handling principles
33
+
34
+ NIST Special Publication 800-86 (Guide to Integrating Forensic
35
+ Techniques into Incident Response) establishes the principles
36
+ this skill follows:
37
+
38
+ - Acquire evidence using techniques that preserve the original
39
+ state.
40
+ - Document everything — who, what, when, where, how.
41
+ - Use cryptographic hashing to detect any modification after
42
+ acquisition.
43
+ - Limit access to evidence to a documented chain of custody.
44
+
45
+ The pentest case isn't a forensic incident, but the same
46
+ principles apply: the evidence we produce will be examined by
47
+ parties we don't fully control, and they need objective grounds
48
+ to trust it.
49
+
50
+ ## SHA-256 vs SHA-3 vs SHA-512
51
+
52
+ The skill uses SHA-256. Reasons:
53
+
54
+ - **Universally available.** Python's `hashlib`, Linux's
55
+ `sha256sum`, macOS's `shasum`, Windows's `Get-FileHash`. No
56
+ party verifying the manifest needs to install anything special.
57
+ - **No known practical preimage attacks** as of 2026. Collision
58
+ attacks on SHA-256 have been theorized but not demonstrated.
59
+ - **Output size (64 hex chars) is human-tractable** for spot
60
+ checks.
61
+
62
+ SHA-3 is fine — academically preferred for new designs — but
63
+ tooling is less universal. SHA-512 is fine too — slightly slower,
64
+ larger output. For evidence-integrity purposes, SHA-256 is
65
+ sufficient and the most portable choice. If your customer's policy
66
+ requires SHA-512, the skill could be extended to emit both.
67
+
68
+ MD5 and SHA-1 are NOT acceptable. Both have practical collision
69
+ attacks. Don't use them for evidence integrity even if old tooling
70
+ defaults to them.
71
+
72
+ ## GPG detached signatures
73
+
74
+ A GPG detached signature is a separate file (typically `.asc` or
75
+ `.sig`) that contains a cryptographic signature over the contents
76
+ of the original file, made with the signer's private key. Anyone
77
+ with the signer's public key can verify:
78
+
79
+ - The signature was made by the holder of the private key.
80
+ - The signed content hasn't been modified since signing.
81
+
82
+ Detached signatures are preferred over inline signatures because
83
+ the original file remains unchanged — easier to feed to tools that
84
+ expect the original format.
85
+
86
+ The skill produces `manifest.sha256.asc` alongside the
87
+ `manifest.sha256`. Verification flow:
88
+
89
+ 1. `gpg --verify manifest.sha256.asc manifest.sha256` — confirms
90
+ the manifest is signed by the claimed signer.
91
+ 2. `sha256sum -c manifest.sha256` — confirms the manifest's
92
+ contents match the on-disk files.
93
+
94
+ Both checks together: the signer attests that the manifest is
95
+ correct, AND the manifest is currently correct against the
96
+ archive.
97
+
98
+ ## Archive format choices
99
+
100
+ The skill uses gzip-compressed tar (`.tar.gz`) for the optional
101
+ portable archive. Comparison:
102
+
103
+ | Format | Tooling | Compression | Notes |
104
+ |---|---|---|---|
105
+ | `.tar.gz` | universal (Linux/macOS/Windows-WSL) | Good | Preserves Unix permissions, mtimes |
106
+ | `.zip` | universal (incl. Windows native) | Good | Loses some Unix metadata; password-protect is weak |
107
+ | WORM (Write-Once Read-Many) media | requires WORM library | n/a | Strongest integrity claim; expensive |
108
+
109
+ Tar.gz is the practical choice. WORM is the strongest claim but
110
+ operationally rare outside specialized forensic shops. The
111
+ manifest provides equivalent integrity guarantees without the
112
+ operational burden.
113
+
114
+ ## Retention horizons per jurisdiction
115
+
116
+ How long to keep pentest evidence depends on the jurisdiction and
117
+ the customer's regulatory posture. Common defaults:
118
+
119
+ | Driver | Typical retention |
120
+ |---|---|
121
+ | Statute of limitations on unauthorized-access offences (US) | 5 years |
122
+ | Statute of limitations (UK, CMA offences) | 6 years |
123
+ | SOC2 audit evidence | 7 years |
124
+ | ISO 27001 audit evidence | 5 years |
125
+ | PCI DSS evidence | 1-3 years (varies by control) |
126
+ | HIPAA breach evidence | 6 years from creation or last effective date |
127
+ | Customer-contractual retention | varies — read the engagement contract |
128
+
129
+ The skill doesn't enforce retention — that's a storage-policy
130
+ concern. The skill ensures the evidence is portable and verifiable
131
+ for whatever retention period applies.
132
+
133
+ ## Out-of-tree path detection
134
+
135
+ A finding that references a file at `/home/tester/notes.md` is a
136
+ chain-of-custody problem: when the engagement archive is moved to
137
+ the customer's storage, that file won't come along. The finding
138
+ becomes uncheckable.
139
+
140
+ The skill scans `findings/*.json` for path-shaped string values in
141
+ the `evidence` dicts and flags any absolute path that isn't within
142
+ the engagement directory tree. The remediation is to copy the
143
+ referenced file INTO the engagement tree, OR change the finding to
144
+ not reference the out-of-tree path.
145
+
146
+ ## When the customer disputes the archive
147
+
148
+ Two failure modes:
149
+
150
+ ### "The archive is incomplete"
151
+
152
+ Customer claims they didn't get all the evidence. Resolution:
153
+
154
+ 1. Run this skill against the archive directory; the report lists
155
+ every file with its hash.
156
+ 2. Compare the list against the customer's expected file list.
157
+ 3. If files are missing from the archive, restore from the
158
+ tester's working copy and re-archive.
159
+ 4. If the customer's expected list includes files that were never
160
+ in scope, document that in the resolution communication.
161
+
162
+ ### "The archive has been modified"
163
+
164
+ Customer claims the evidence doesn't match what they saw during
165
+ the engagement. Resolution:
166
+
167
+ 1. Run `sha256sum -c manifest.sha256` against the archive
168
+ directory. If output is "OK," the archive is internally
169
+ consistent.
170
+ 2. If the customer's claim is that the EVIDENCE itself was
171
+ manipulated (not the archive), compare against the daily
172
+ snapshots taken during the engagement (if available).
173
+ 3. If no daily snapshots were taken, the integrity claim depends
174
+ on the original manifest signature and any external retention
175
+ timestamps (e.g. WORM storage, email of the manifest at
176
+ engagement close).
177
+
178
+ The skill's daily-snapshot pattern (see PLAYBOOK.md) is the cheap
179
+ preventive measure for this dispute class.
180
+
181
+ ## Why the manifest is in standard sha256sum format
182
+
183
+ The skill could emit a custom JSON manifest. The sha256sum format
184
+ is preferred because:
185
+
186
+ - Standard Unix tooling (`sha256sum -c`) verifies it without any
187
+ custom code.
188
+ - A customer or legal counsel can verify the manifest 10 years
189
+ from now even if this skill no longer exists.
190
+ - The format is line-oriented; diffs are readable.
191
+
192
+ The standard format is one line per file: 64-hex-char digest,
193
+ exactly two spaces, then the file's relative path. Both Linux's
194
+ `sha256sum` and macOS's `shasum -a 256` produce and verify this
195
+ form.