Skip to content

feat(core): add recursive key-based redaction#371

Merged
HugoRCD merged 2 commits into
mainfrom
feat/recursive-key-redaction
Jun 10, 2026
Merged

feat(core): add recursive key-based redaction#371
HugoRCD merged 2 commits into
mainfrom
feat/recursive-key-redaction

Conversation

@HugoRCD

@HugoRCD HugoRCD commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Path-pattern redaction: dot-notation with glob support (e.g., shorthand password → any-depth match), key-name globs, and custom replacements.
  • Documentation

    • Comprehensive docs and examples updated to show path patterns, semantics, built-ins, and replacement behavior; updated configuration references and guides.
  • Refactor

    • Audit redaction preset simplified to rely on key-based/path-pattern matching for broader coverage.
  • Tests

    • Expanded tests covering exact paths, glob behavior, shorthand equivalence, case-insensitivity, and error-tolerant regex handling.

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
evlog-docs Ready Ready Preview, Comment, Open in v0 Jun 10, 2026 8:37pm
just-use-evlog Ready Ready Preview, Comment Jun 10, 2026 8:37pm

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Thank you for following the naming conventions! 🙏

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 76f5e890-5eb6-4a36-bace-889406247b31

📥 Commits

Reviewing files that changed from the base of the PR and between 03280d2 and 5d966a2.

📒 Files selected for processing (11)
  • .changeset/recursive-key-redaction.md
  • apps/docs/content/2.learn/6.redaction.md
  • apps/docs/content/4.use-cases/4.audit/05.compliance.md
  • apps/docs/content/6.reference/1.configuration.md
  • apps/docs/skills/build-audit-logs/SKILL.md
  • packages/evlog/src/audit.ts
  • packages/evlog/src/redact.ts
  • packages/evlog/src/types.ts
  • packages/evlog/src/utils.ts
  • packages/evlog/test/core/audit.test.ts
  • packages/evlog/test/core/redact.test.ts

📝 Walkthrough

Walkthrough

Adds dot-notation path globs to RedactConfig.paths, centralizes glob compilation, and implements compiled path matchers with recursive path-based redaction helpers. Integrates matchers into redactEvent and auditDiff, updates the auditRedactPreset to use key-name globs, and updates docs and tests for the new path-glob semantics.

Changes

Path-Glob Redaction

Layer / File(s) Summary
Documentation and changelog
.changeset/recursive-key-redaction.md, apps/docs/content/2.learn/6.redaction.md, apps/docs/content/4.use-cases/4.audit/05.compliance.md, apps/docs/content/6.reference/1.configuration.md, apps/docs/skills/build-audit-logs/SKILL.md
Adds changeset and updates docs to describe dot-notation path globs, shorthand (password**.password), path vs pattern behavior, updated examples, and configuration reference.
Glob utility
packages/evlog/src/utils.ts
Adds globToRegExp(pattern, separator) with caching and separator-aware segment rules; updates matchesPattern to use the new helper.
Path matcher compilation and core redaction helpers
packages/evlog/src/redact.ts
Adds RedactPathMatchers, normalizeRedactPathPattern, compileRedactPathMatchers, addPathGlobPattern, matchesRedactPath, redactPathsInTree (in-place), and redactValueByPaths (non-mutating). Removes old segment-based helper.
redactEvent integration and config normalization
packages/evlog/src/redact.ts, packages/evlog/src/types.ts
redactEvent now compiles path matchers and applies redactPathsInTree when present. normalizeRedactConfig uses deserializeRegexList to parse patterns; RedactConfig JSDoc updated to document path-glob syntax and replacement semantics.
auditDiff refactor and preset update
packages/evlog/src/audit.ts
auditDiff precomputes pathMatchers via compileRedactPathMatchers(options.redactPaths) and calls redactValueByPaths; auditRedactPreset.paths changed to credential/header key-name globs.
Tests for path-glob behavior and regex deserialization
packages/evlog/test/core/audit.test.ts, packages/evlog/test/core/redact.test.ts
Adds extensive tests for exact paths, shorthand and glob semantics, non-recursive full-value replacement, case-insensitive header matching, nested audit redaction via preset, and normalizeRedactConfig regex deserialization/warning behavior.

Sequence Diagram

sequenceDiagram
  participant Config as RedactConfig
  participant Event as redactEvent
  participant Compiler as compileRedactPathMatchers
  participant Matchers as RedactPathMatchers
  participant Redactor as redactPathsInTree
  participant Output as RedactedEvent

  Config->>Event: call redactEvent(event, config)
  Event->>Compiler: compileRedactPathMatchers(config.paths)
  Compiler->>Matchers: return compiled matchers
  Event->>Redactor: redactPathsInTree(eventTree, Matchers, config.replacement)
  Redactor->>Output: mutated/redacted event
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • HugoRCD/evlog#365: Modifies core redaction pipeline in packages/evlog/src/redact.ts, particularly redactEvent flow and non-mutating redaction patterns that directly intersect with this PR's path-glob matcher and redaction changes.

Suggested labels

feature

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description provided by the author, leaving required sections like linked issue, change rationale, and checklist items unfilled. Add a PR description that includes a linked issue, explanation of what problem this solves, and completion of the provided checklist.
Docstring Coverage ⚠️ Warning Docstring coverage is 64.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(core): add recursive key-based redaction' is specific and directly related to the main changes in this PR, which refactor path-based redaction to support glob patterns and key-name matching at any nesting depth.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/recursive-key-redaction

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.

@pkg-pr-new

pkg-pr-new Bot commented Jun 10, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/evlog@371
npm i https://pkg.pr.new/@evlog/nuxthub@371

commit: 5d966a2

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
packages/evlog/src/types.ts (1)

119-126: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep the builtins: false docs aligned with the new key-based selectors.

Line 121 still says disabling built-ins leaves only custom paths/patterns, but keys and keyPatterns still apply too. The public contract is correct in code; the JSDoc is now the part that's stale.

📝 Proposed doc fix
-   * - `false` → no built-ins, only custom `paths`/`patterns`
+   * - `false` → no built-ins, only custom `paths`/`keys`/`keyPatterns`/`patterns`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/evlog/src/types.ts` around lines 119 - 126, Update the JSDoc for the
builtins?: property to reflect the new key-based selectors: clarify that setting
builtins: false disables only built-in patterns but custom paths/patterns as
well as keys and keyPatterns still remain active; reference the builtins
property and the related keys and keyPatterns options so readers know those
selectors still apply when builtins is false (edit the comment block above
builtins?: in types.ts).
packages/evlog/src/audit.ts (2)

849-876: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make the built-in header redaction case-insensitive.

With keys only containing lowercase names, Authorization, Cookie, and Set-Cookie are not redacted by the shared exact-match key matcher. That contradicts the preset docs and can leak credentials when callers log header objects with canonical casing. Prefer keyPatterns like /^authorization$/i over exact lowercase header keys here.

Proposed change
 export const auditRedactPreset: RedactConfig = {
   keys: [
     'password',
     'passwordHash',
     'token',
     'apiKey',
     'secret',
     'accessToken',
     'refreshToken',
     'cardNumber',
     'cvv',
     'ssn',
-    'authorization',
-    'cookie',
-    'set-cookie',
   ],
+  keyPatterns: [
+    /^authorization$/i,
+    /^cookie$/i,
+    /^set-cookie$/i,
+  ],
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/evlog/src/audit.ts` around lines 849 - 876, The preset
auditRedactPreset currently lists header names in the keys array using lowercase
(e.g., 'authorization', 'cookie', 'set-cookie') which fails to match
canonical-cased headers; update auditRedactPreset so header redaction is
case-insensitive by removing those exact-header entries from keys and adding
equivalent case-insensitive regexes in a new or existing keyPatterns array
(e.g., /^authorization$/i, /^cookie$/i, /^set-cookie$/i); keep the other
credential keys unchanged and ensure the redaction logic consumes keyPatterns
alongside keys when matching (refer to auditRedactPreset and the
keys/keyPatterns match usage).

327-358: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Restore redactPaths compatibility before routing through the key matcher.

buildKeyMatcher() only matches exact key names, so documented inputs like redactPaths: ['user.password'] no longer match /user/password here. That silently stops redaction for existing callers and can leak secrets into the patch plus includeBefore / includeAfter snapshots. Keep dotted-path matching for redactPaths, or introduce a separate key-based option and preserve the old contract on this path.

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/docs/skills/build-audit-logs/SKILL.md`:
- Line 285: The page mixes US and UK spellings for authorization/authorisation;
pick one spelling and standardize all occurrences across this skill page
(including keys used in auditRedactPreset and any references in RedactConfig,
e.g., the string "authorization"/"authorisation" and any mentions inside
audit.changes.before/after) so the same variant is used everywhere; update the
auditRedactPreset (or merged RedactConfig) entries and all textual references to
match the chosen variant.

In `@packages/evlog/src/redact.ts`:
- Around line 395-404: deserializeRegexList currently constructs RegExp directly
and will throw on invalid serialized entries; update deserializeRegexList to
validate each entry's shape (allow RegExp, string, or object with string source
and optional string flags), wrap the RegExp construction for each entry in a
try/catch so malformed source/flags are skipped (do not throw the whole
function), and preserve the existing type by returning only successful RegExp
instances (keeping the final filter p is RegExp); reference the
deserializeRegexList function and the patterns/keyPatterns deserialization path
when making this change.
- Around line 68-85: redactValueByKeys currently treats any non-array object as
a plain object and rebuilds it via Object.entries, which corrupts Dates, URLs,
Errors and class instances; change the object-handling branch in
redactValueByKeys so you only recurse into plain objects (e.g. detect plain
objects with Object.getPrototypeOf(value) === Object.prototype ||
Object.getPrototypeOf(value) === null or a similar isPlainObject check) and
leave non-plain objects untouched (return value) unless their key matches
matcher; keep the existing Array.isArray behavior and ensure matcher/replacement
logic still runs for object keys when the object is plain—this prevents
auditDiff from receiving corrupted before/after/patch values.

---

Outside diff comments:
In `@packages/evlog/src/audit.ts`:
- Around line 849-876: The preset auditRedactPreset currently lists header names
in the keys array using lowercase (e.g., 'authorization', 'cookie',
'set-cookie') which fails to match canonical-cased headers; update
auditRedactPreset so header redaction is case-insensitive by removing those
exact-header entries from keys and adding equivalent case-insensitive regexes in
a new or existing keyPatterns array (e.g., /^authorization$/i, /^cookie$/i,
/^set-cookie$/i); keep the other credential keys unchanged and ensure the
redaction logic consumes keyPatterns alongside keys when matching (refer to
auditRedactPreset and the keys/keyPatterns match usage).

In `@packages/evlog/src/types.ts`:
- Around line 119-126: Update the JSDoc for the builtins?: property to reflect
the new key-based selectors: clarify that setting builtins: false disables only
built-in patterns but custom paths/patterns as well as keys and keyPatterns
still remain active; reference the builtins property and the related keys and
keyPatterns options so readers know those selectors still apply when builtins is
false (edit the comment block above builtins?: in types.ts).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0ede3606-c2c9-424b-8aa7-52c5d98453ea

📥 Commits

Reviewing files that changed from the base of the PR and between cf6e6fd and 03280d2.

📒 Files selected for processing (10)
  • .changeset/recursive-key-redaction.md
  • apps/docs/content/2.learn/6.redaction.md
  • apps/docs/content/4.use-cases/4.audit/05.compliance.md
  • apps/docs/content/6.reference/1.configuration.md
  • apps/docs/skills/build-audit-logs/SKILL.md
  • packages/evlog/src/audit.ts
  • packages/evlog/src/redact.ts
  • packages/evlog/src/types.ts
  • packages/evlog/test/core/audit.test.ts
  • packages/evlog/test/core/redact.test.ts

Comment thread apps/docs/skills/build-audit-logs/SKILL.md Outdated
Comment thread packages/evlog/src/redact.ts
Comment thread packages/evlog/src/redact.ts Outdated
@HugoRCD HugoRCD merged commit 0625240 into main Jun 10, 2026
18 checks passed
@HugoRCD HugoRCD deleted the feat/recursive-key-redaction branch June 10, 2026 21:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant