Files
chanora/poc/diagnostics-redaction-spike/README.md
T
EdisonJwa 06ec6f2965 feat(poc/diagnostics): add diagnostics-redaction spike
Proof-of-concept proving the diagnostics-redaction exit criterion from
docs/architecture/proof-of-concept-plan.md §2:
  "Password and identity-secret samples are redacted."

Full coverage of the audit-report test matrix in
docs/security/diagnostic-redaction-audit-report.md §4
(REDACT-TC-001..010), plus two sanity tests.

The spike ships:
  - RedactionPolicy: typed catalogue of regex rules
    (identity-base64-blob, password-kv, ts3server-url-password,
     authorization-bearer, linux/windows/macos user-path) with
    optional capture-group narrowing.
  - Structured-field redaction keyed on case-insensitive name
    substrings (password, secret, token, ...).
  - Bundle-level switches: chat and channel tree excluded by
    default per audit-report §5.
  - KnownSecretRegistry: literal-substring scrub for secrets the
    host application has already loaded into memory (defense in
    depth that regexes alone cannot guarantee — closes the gap
    behind REDACT-TC-002).
  - Length cap (MAX_PROTOCOL_STRING_LEN = 256) with truncation
    marker for REDACT-TC-009.
  - UTF-8 preserved in non-sensitive fields per REDACT-TC-010 /
    ADR-008.

Test suite (12/12 PASS on 2026-05-13):
  REDACT-TC-001 server password in connection data
  REDACT-TC-002 identity secret in storage error (via KnownSecretRegistry)
  REDACT-TC-003 server URL with password field
  REDACT-TC-004 chat text excluded by default
  REDACT-TC-005 channel name with Unicode excluded by default
  REDACT-TC-006 nickname with Unicode preserved in safe field
  REDACT-TC-007 local file path user segment minimized
  REDACT-TC-008 mixed sensitive bundle (whole-bundle JSON scan)
  REDACT-TC-009 long hostile protocol string truncated
  REDACT-TC-010 multilingual safe text preserved
  + known-secret literal scrub
  + empty registered secret ignored

Out of scope: tracing-subscriber integration, diagnostic export
file format, memory/core dumps, performance, adversarial regex
evasion beyond trivial cases. These belong to chanora_diagnostics.

Authority: PoC plan §2, docs/security/diagnostic-redaction-audit-report.md,
SRS-093, SysRS-152/154/155.
Not product code; not promoted into chanora_diagnostics.
2026-05-14 12:26:49 +08:00

3.1 KiB

Diagnostics Redaction Spike

Chanora proof-of-concept. Not product code.

Field Value
PoC name diagnostics-redaction-spike
PoC plan docs/architecture/proof-of-concept-plan.md §2
Purpose Prove redaction of secrets before logs or diagnostic export
Exit criterion "Password and identity-secret samples are redacted"
Authority docs/security/diagnostic-redaction-audit-report.md §2 + §4 + §5; SRS-093, SysRS-152/154/155, SDD §5

What it proves

  • A typed RedactionPolicy carrying:
    • regex-driven rules (with optional capture-group narrowing so the rule can scrub a value while keeping the surrounding context);
    • structured-field redaction keyed on case-insensitive name substrings (password, secret, token, …);
    • bundle-level switches (chat / channel tree default to excluded).
  • A Redactor that applies the policy to free text and to a typed DiagnosticBundle.
  • A KnownSecretRegistry for literal scrubbing — the strongest defence when the host has already loaded the actual secret value into memory. This is what closes the gap that regexes alone cannot fully cover (REDACT-TC-002).
  • A length cap (MAX_PROTOCOL_STRING_LEN) so hostile / oversized protocol strings cannot grow the diagnostic surface (REDACT-TC-009).
  • UTF-8 preservation for benign multilingual text (REDACT-TC-010 / ADR-008).

Coverage of the audit-report test matrix

All ten REDACT-TC-001..010 entries are covered (see VERIFICATION.md).

Layout

diagnostics-redaction-spike/
  src/
    lib.rs               # crate root, re-exports, REDACTION_MARKER
    policy.rs            # RedactionRule, RedactionPolicy, default policy
    redactor.rs          # Redactor, KnownSecretRegistry
    bundle.rs            # DiagnosticBundle DTO + bundle-level redaction
    main.rs              # diagnostics-redaction-cli driver
  tests/
    redaction.rs         # 12 tests; REDACT-TC-001..010 + sanity
  Cargo.toml

Reproduce

Requires Rust stable (developed against 1.95).

cargo test
echo 'INFO password=hunter2 path=/home/alice/x' | cargo run --bin diagnostics-redaction-cli

Scope boundaries

  • Not a tracing layer. Production code in chanora_diagnostics will wire the redactor as a tracing-subscriber layer to enforce redaction at write-time, not via post-processing. The mechanism here is the same; the integration surface is not.
  • No diagnostic bundle file format. The spike only redacts the in-memory struct; the actual export format (zip / json-lines / etc.) is owned by chanora_diagnostics.
  • No threat-model coverage of memory dumps, core dumps, or kernel logs. That is docs/security/threat-model.md territory.
  • No language-aware redaction. The Unicode policy is "preserve multilingual text in non-sensitive fields; do not introspect it."
  • No PII discovery. This is a deny-list redactor; it does not attempt to detect previously-unknown secrets by entropy heuristics.

Verification log

See VERIFICATION.md in this directory.