Skip to content

feat(sanitizer): configurable secret policy, PEM/JWT detection, honest docs - #186

Merged
chrisleekr merged 1 commit into
mainfrom
feat/secret-scanner
Jun 20, 2026
Merged

feat(sanitizer): configurable secret policy, PEM/JWT detection, honest docs#186
chrisleekr merged 1 commit into
mainfrom
feat/secret-scanner

Conversation

@chrisleekr

Copy link
Copy Markdown
Owner

Why

The secret scanner had two honest problems flagged in review: (1) it only matched ~9 vendor key formats, so a PEM private key or JWT pasted into config flowed straight into the vault, and (2) the docs oversold it as a secret scanner when it is really a known-credential-format guard. There was also no way to exempt a legitimate high-entropy value the base64 redactor would silently corrupt. PR #185 added the [security] config surface (recorded but inert); this PR wires it in and retires the "inert" note.

Third PR in the series (follows #184, #185).

What

  • Configurable SecretPolicy resolved from [security] via securityToPolicy, threaded through scanForSecrets (the push-time artifact-body gate) and redactSecretLiterals/sanitizeAndNormalizeJson (per-adapter JSON redaction in claude/codex/cursor/vscode).
    • secretScan: standard (built-in patterns) | strict (+ JWT) | off (disables the artifact-body scan).
    • allowSecretValues: exempts exact literals from detection and base64 redaction (fixes the silent base64 false-positive corruption).
    • redactBase64Values: disable the broad base64 whole-value redaction for configs that legitimately store base64.
  • Breadth: PEM private-key headers detected in every mode (unambiguous); JWTs added in strict.
  • Fail-safe: off disables the artifact-body scan, but skill-bundle interiors are always scanned at standard (the walker is not policy-threaded), and config set always scans values regardless of off (config is plaintext).
  • Honesty docs: architecture/commands/operations now describe the scan as a known-credential-format guard, not a general secret scanner, list exactly what is and isn't covered, and document the tuning knobs.

Security (caught in review)

The first cut of the allowlist used text.match() (first occurrence only): an allow-listed decoy earlier in a file would have masked a real secret of the same shape later — a fail-open leak when allowSecretValues is set. Fixed to iterate every occurrence with matchAll and exempt only exact allow-listed literals; DEFAULT_SECRET_POLICY is frozen against mutation. Default behaviour (no [security]) is byte-identical to before — verified by the unchanged existing sanitizer/adapter suites.

Tests

New "secret policy" unit block + the decoy-masking regression test; end-to-end push tests for secretScan=off (lets a key through), strict (JWT aborts, standard clean), and allowSecretValues (embedded key exempted); adapter test proving the policy is honoured (off → unredacted). Full suite: 936 pass / 0 fail.

CI note

bun test exits non-zero on the per-file coverage floor; CI treats 0-fail as success.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@chrisleekr, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 5 minutes and 50 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5db8f108-3536-4ebe-9675-628fabc6946c

📥 Commits

Reviewing files that changed from the base of the PR and between b9d39ae and 39f96ab.

📒 Files selected for processing (14)
  • docs/architecture.md
  • docs/commands.md
  • docs/operations.md
  • src/agents/claude/__tests__/sanitize.test.ts
  • src/agents/claude/index.ts
  • src/agents/claude/sanitize.ts
  • src/agents/codex/index.ts
  • src/agents/cursor/index.ts
  • src/agents/vscode/index.ts
  • src/commands/__tests__/push.test.ts
  • src/commands/push.ts
  • src/config/schema.ts
  • src/core/__tests__/sanitizer.test.ts
  • src/core/sanitizer.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant