feat(crafter): redact secrets from AI coding sessions before CAS upload

Merged
JI
2mo ago
+2616-207

AI coding session evidence carries the raw conversation transcript in data.raw_session, which routinely includes whatever the agent read or printed, credentials included. That content was stored in the CAS verbatim.

Secrets are now detected and replaced before the material is stored.

The file on disk is left untouched and remains what policies are evaluated against, so a secret-detection policy still sees what the agent actually captured. The recorded digest therefore describes the redacted artifact rather than the local file, which a chainloop.material.redacted annotation makes explicit; the same annotation is what keeps the policy input consistent on inline CAS backends, where the stored content is otherwise also the policy input.

Any scan failure in attestation add stop the process rather storing unscanned content.
Added a CLI option --skip-secret-redaction is an explicit opt-out, recorded in the attestation as chainloop.material.redaction.skipped so a policy can reject it. What was redacted is published as chainloop.material.redaction.count and chainloop.material.redaction.rules.

Detection lives behind a Scanner interface in a new internal/redaction package, which detects against the document rendered as indented JSON and then rewrites the decoded value tree, so the output cannot be malformed JSON. A convergence loop re-scans after each rewrite, making idempotency a property of the algorithm. Every string leaf is eligible except an explicit set of identifiers, timestamps and file paths the platform joins records on.

Detection uses betterleaks, which also replaces gitleaks as the library backing the GITLEAKS_JSON material parser; the report formats are wire-compatible. github.com/zricethezav/gitleaks/v8 is dropped, and the net effect is two fewer modules.

Assisted by Claude Code.