Skip to content

fix(secrets): span-aware redaction to prevent double-skip and chain-replace bugs#726

Merged
kajogo777 merged 1 commit into
mainfrom
fix/secret-redaction-regressions
May 6, 2026
Merged

fix(secrets): span-aware redaction to prevent double-skip and chain-replace bugs#726
kajogo777 merged 1 commit into
mainfrom
fix/secret-redaction-regressions

Conversation

@ahmedhesham6

Copy link
Copy Markdown
Collaborator

Description

Fix secret redaction regressions that caused fresh secrets to be silently skipped and restoration to chain-replace incorrectly.

Bugs fixed

  1. Double-redaction early-return skip: redact_secrets returned immediately when content.contains("[REDACTED_SECRET:"), so any new secret in the same text was never detected. Overhaul to use span-based overlap checks — existing markers are protected from re-detection while fresh secrets are still redacted.

  2. restore_secrets chain-replacement: Iterating a HashMap and calling String::replace per entry could rewrite previously-restored markers when a secret value resembled another key. Rewrite to walk left-to-right with the marker regex, replacing each marker exactly once in order.

  3. redact_password early-return skip: Same contains("[REDACTED_SECRET:") guard prevented password redaction when any stale marker was present. Fixed with the same span-based overlap filter.

  4. CLI secret leak in prompts: User input and feedback in mode_async.rs and mode_interactive.rs were not routed through SecretManager::redact_and_store_secrets, so secrets reached the LLM in plaintext. wired redaction into both paths.

Related Issues

Fixes secret redaction regressions reported by Abdalla.

Changes Made

  • libs/shared/src/secrets/mod.rs: Span-aware redaction with find_protected_spans / overlaps_protected_span; left-to-right restore_secrets using REDACTED_SECRET_MARKER_RE regex; redact_password uses same span filter
  • cli/src/commands/agent/run/mode_async.rs: Route user input + feedback through SecretManager::redact_and_store_secrets
  • cli/src/commands/agent/run/mode_interactive.rs: Route user input through SecretManager::redact_and_store_secrets
  • libs/shared/tests/secret_redaction_regressions.rs: 18-test regression suite

Testing

  • All tests pass locally (cargo test -p stakpak-shared --test secret_redaction_regressions — 18/18)
  • cargo clippy --all-targets -- -D warnings — zero warnings
  • cargo fmt --check — clean
  • Added tests for all new functionality

Breaking Changes

None — public API signatures unchanged; internal logic fixes only.

…eplace bugs

The early-return check `content.contains("[REDACTED_SECRET:")` caused fresh
secrets in the same text to be silently skipped. Replace it with overlap-based
span protection that shields existing markers while still detecting new secrets.

Rewrite restore_secrets to walk the string left-to-right using the marker regex,
eliminating HashMap-iteration-based replacement that could chain-replace when a
secret value looked like another key.

Wire SecretManager::redact_and_store_secrets into async and interactive agent
modes so user prompts and feedback are redacted before reaching the LLM.

Add 18-test regression suite covering stale markers, session-growth redaction,
shell-special chars in restore, adjacent markers, and determinism.
@ahmedhesham6 ahmedhesham6 requested a review from kajogo777 May 5, 2026 18:34

@kajogo777 kajogo777 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kajogo777 kajogo777 merged commit 57fc94c into main May 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants