Skip to content

Implement privacy redaction for event payloads and update docs - #268

Open
hoangsonww wants to merge 2 commits into
masterfrom
cursor/privacy-ingest-controls-a516
Open

Implement privacy redaction for event payloads and update docs#268
hoangsonww wants to merge 2 commits into
masterfrom
cursor/privacy-ingest-controls-a516

Conversation

@hoangsonww

Copy link
Copy Markdown
Owner

This pull request introduces a configurable ingest-time privacy redaction feature, updates documentation to reflect the new privacy controls, and exposes a new API for managing privacy settings. The privacy policy allows secrets and sensitive information to be redacted from event payloads before they are persisted, with built-in detectors and customizable toggles. The changes also update the UI and CLI documentation, and add internationalized API docs.

Privacy Redaction Feature:

  • Added a configurable ingest-time privacy policy that redacts secrets from event payloads before they are written to the database. Built-in detectors cover secret-like keys, API-key/Bearer/PEM patterns, with optional email masking and home-directory path hashing. The redaction only affects persisted data; in-memory payloads remain unmodified. (README.md, ARCHITECTURE.md) [1] [2]
  • Introduced the lib/privacy.js module for ingest-time privacy redaction and described its integration points and fail-safe behavior. (ARCHITECTURE.md)

API and CLI Additions:

  • Exposed new API endpoints for privacy policy management: GET/PUT /api/settings/privacy and POST /api/settings/privacy/preview for retrieving, updating, and previewing redaction policies. (README.md, README-CN.md, README-KO.md, README-VN.md) [1] [2] [3] [4]
  • Added CLI commands for showing and updating the ingest privacy redaction policy. (README.md)

Documentation and UI Updates:

  • Updated documentation and architecture diagrams to include privacy controls in the Settings UI and API. (client/README.md, ARCHITECTURE.md) [1] [2]
  • Clarified that privacy settings are preserved during data export/import and when clearing all data. (ARCHITECTURE.md)

Add a configurable privacy policy that redacts secrets from event
payloads before SQLite writes, without changing live session/agent/token
processing. Includes Settings UI with preview, API endpoints, CLI
support, OpenAPI docs, snapshot update, and server tests (MVP for #148).
@hoangsonww hoangsonww self-assigned this Aug 1, 2026
@hoangsonww hoangsonww added the bug Something isn't working label Aug 1, 2026
Copilot AI review requested due to automatic review settings August 1, 2026 18:19
@hoangsonww hoangsonww added documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers question Further information is requested labels Aug 1, 2026
@cursor

cursor Bot commented Aug 1, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Copilot AI 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.

Pull request overview

Adds an ingest-time privacy redaction system to mask secrets in persisted events.data (while keeping in-memory hook payloads intact), exposing management via Settings UI + REST + CLI, and updating API/DB/docs/wiki/i18n accordingly.

Changes:

  • Introduce server/lib/privacy.js + privacy_settings table, and apply redaction at hook ingest + history import persistence.
  • Add REST endpoints GET/PUT /api/settings/privacy and POST /api/settings/privacy/preview, plus OpenAPI/docs updates.
  • Add Settings → Privacy UI (with i18n + snapshots), and a new ccam privacy CLI command.

Reviewed changes

Copilot reviewed 29 out of 31 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
wiki/sw.js Bump wiki cache version.
wiki/index.html Update wiki Settings copy + i18n content cache-bust.
wiki/i18n-content.js Update wiki body-content translations to mention privacy redaction.
server/routes/settings.js Add privacy settings + preview endpoints.
server/routes/hooks.js Persist redacted event payloads via serializeEventData().
server/README.md Document new privacy endpoints.
server/openapi-extra/misc.js Add OpenAPI schemas + paths for privacy endpoints.
server/lib/privacy.js Implement ingest-time privacy redaction + settings persistence.
server/db.js Add privacy_settings table + prepared statements.
server/tests/privacy.test.js Add unit + HTTP tests for privacy feature.
scripts/import-history.js Apply same redaction policy when importing legacy history.
README.md Document privacy feature + CLI + API routes.
README-VN.md Add privacy endpoints to VN README API table.
README-KO.md Add privacy endpoints to KO README API table.
README-CN.md Add privacy endpoints to CN README API table.
docs/DATABASE.md Document privacy_settings table.
docs/CLI.md Document ccam privacy commands.
docs/API.md Add privacy endpoint section + usage notes.
client/src/pages/Settings.tsx Add Privacy section to Settings screen.
client/src/pages/tests/screens.snapshot.test.tsx Mock privacy endpoints in UI snapshot harness.
client/src/pages/tests/snapshots/screens.snapshot.test.tsx.snap Update Settings snapshots to include Privacy section.
client/src/lib/types.ts Add PrivacySettings type.
client/src/lib/api.ts Add client API wrapper for privacy endpoints.
client/src/i18n/locales/en/settings.json Add Settings → Privacy strings (EN) + subtitle update.
client/src/i18n/locales/zh/settings.json Add Settings → Privacy strings (ZH) + subtitle update.
client/src/i18n/locales/vi/settings.json Add Settings → Privacy strings (VI) + subtitle update.
client/src/i18n/locales/ko/settings.json Add Settings → Privacy strings (KO) + subtitle update.
client/src/components/PrivacySettings.tsx New UI panel for toggles + preview before/after.
client/README.md Update client architecture diagram label for Settings.
bin/ccam.js Add ccam privacy CLI command + PUT helper.
ARCHITECTURE.md Document privacy module + settings endpoints in architecture map.
Files not reviewed (1)
  • wiki/i18n-content.js: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/lib/privacy.js
Comment on lines +336 to +340
function serializeEventData(payload, settingsOverride) {
const { data } = redactForStorage(payload, settingsOverride);
if (data == null) return null;
return JSON.stringify(data);
}
Comment thread server/lib/privacy.js
Comment on lines +143 to +145
// Common absolute home roots on Unix / macOS for path hashing even when
// the process home isn't the path embedded in a payload (e.g. imported
// history from another machine still shows /Users/<name>/...).
Comment on lines +391 to +395
settings: {
allOf: [{ $ref: "#/components/schemas/PrivacySettings" }],
description: "Optional policy override for the preview (does not change saved settings).",
},
},
Comment thread server/routes/settings.js
Comment on lines +296 to +297
const result = previewRedaction(payload, override);
res.json(result);
Comment on lines +188 to +205
{toggles.map(({ key, label, desc }) => {
const locked = saving || (key !== "enabled" && !settings.enabled);
return (
<div
key={key}
className={`flex items-start gap-3 py-2 border-t border-border/60 first:border-t-0 first:pt-0 ${
locked ? "opacity-50" : ""
}`}
>
<div className="min-w-[11rem] flex-shrink-0">
<Checkbox
checked={Boolean(settings[key])}
onChange={(checked) => {
if (locked) return;
void update({ [key]: checked });
}}
label={label}
/>
Comment thread server/lib/privacy.js
Comment on lines +230 to +234
if (value && typeof value === "object") {
// Preserve Date / Buffer-like by treating unknowns as opaque
if (Object.getPrototypeOf(value) !== Object.prototype && !(value instanceof Object)) {
return value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested

Projects

Development

Successfully merging this pull request may close these issues.

3 participants