pharn-logging-masking-audit

star 0

Deep PII-masking audit on the non-analytics telemetry surfaces: error tracking (Sentry et al.), application logging (Pino/Winston/Bunyan/console), and request-response logging middleware. Three parallel sonnet agents, one per surface. Standalone — not wired into /pharn-ship.

pharn-dev By pharn-dev schedule Updated 6/11/2026

name: pharn-logging-masking-audit skill: "pharn-logging-masking-audit" version: "0.33.2" description: "Deep PII-masking audit on the non-analytics telemetry surfaces: error tracking (Sentry et al.), application logging (Pino/Winston/Bunyan/console), and request-response logging middleware. Three parallel sonnet agents, one per surface. Standalone — not wired into /pharn-ship." kind: pharn-owned module: pharn-audits audit_class: privacy-focused focus: "Error-tracking + application-logging + request-logging PII masking" model_tier: sonnet recommended_effort: medium priority: pharn-owned depends_on: [] soft_depends_on:

  • "privacy-shield" pipeline_wired: false v1_scope: in:
    • "Sentry (init config, setUser, captureException, breadcrumbs)"
    • "Pino (redact config, log call sites, serializers)"
    • "Winston (format config, log call sites)"
    • "Bunyan (serializers, log call sites)"
    • "console (raw console calls)"
    • "Request-response logging middleware (Next.js, morgan, fastify, custom)"
    • "Generic error tracking (Bugsnag, Rollbar, Honeybadger — light coverage)" out:
    • "Log aggregation tooling configs (CloudWatch, DataDog, Splunk, Loki)"
    • "Log retention / archival policies"
    • "Log transport TLS configuration"
    • "Custom logging libraries outside the listed primaries"
    • "Runtime config mutations (flagged for manual review)" reads:
  • ".claude/CONSTITUTION.md"
  • "features/*/PLAN.md"
  • "pharn.config.json"
  • "**/sentry*.{ts,tsx,js,jsx}"
  • "**/instrumentation*.{ts,js}"
  • "**/logger*.{ts,js}"
  • "**/middleware*.{ts,js}"
  • "**/*.{ts,tsx,js,jsx}" writes:
  • ".claude/audits/logging-masking-.md" modes:
  • default flags:
  • --scope <error-tracking|logging|request|all>
  • --features
  • --quick
  • --export <md|html> audit_severity:
  • "🔴 LEAK — PII actually leaks to logs/error tracking"
  • "🟠 AT RISK — potential leak / config gaps / dynamic content"
  • "🟢 BEST PRACTICE — defense-in-depth" pharn_version: "0.67.1" seal: "PHARN ✓ reviewed"

/pharn-logging-masking-audit

A focused, deep audit on PII masking across the non-analytics telemetry surfaces — error tracking (Sentry and similar), application logging (Pino / Winston / Bunyan / raw console), and request-response logging middleware. Three parallel sonnet agents cover the three surfaces: error-tracking interprets error-tracker init config and usage call sites; structured-logging scans logger configuration and log call sites; request-response-logging scans middleware that captures HTTP request/response data. Findings are emitted in a standing audit-finding schema and consolidated into a structured report. Agents run in parallel; the audit is resilient — an individual agent error or an inapplicable surface is recorded in the report and never halts the other agents.

This is the second Tier 2 audit skill in pharn-audits, and with /pharn-posthog-masking-audit it completes Tier 2 (2 of 2). Tier 1 (privacy, security, accessibility, drift-check) audits against external standards or internal consistency; Tier 2 audits go deep on a specific telemetry surface. Where the PostHog audit owns the analytics surface, this audit owns error tracking and logging.

Relationship to the other telemetry-masking tooling

Three siblings divide telemetry masking; none replaces the others, and they are expected to overlap on obvious cases.

/pharn-privacy-audit's telemetry auditor /pharn-posthog-masking-audit /pharn-logging-masking-audit (this audit)
Scope Broad sweep — analytics + error tracking + logs Analytics (PostHog) — deep Error tracking + application logging + request logging — deep
Surface One cross-cutting auditor config + events + dom error-tracking + structured-logging + request-response-logging
When Quarterly comprehensive privacy review Before deploying session replay / new events Before deploying Sentry, when adding logging, after a near-miss
Refs GDPR articles (telemetry hygiene framing) posthog_rule_ref + gdpr_ref tool_rule_ref + gdpr_ref
Output Findings in the privacy-audit report PostHog masking report Logging masking report in .claude/audits/

The three deep audits divide telemetry along tool lines; the privacy-audit telemetry auditor catches what they all share. Both deep audits should agree with the broad telemetry auditor on obvious cases; they go deeper where the broad audit doesn't have room. Run this audit when you need depth on Sentry-class error tracking and on Pino/Winston/Bunyan/console + request-logging middleware.

Analytics masking (PostHog capture properties, session replay) is out of scope here — that surface belongs to /pharn-posthog-masking-audit and the broad telemetry auditor. This audit does not cover analytics.

The three PII-leak surfaces this audit covers

  • Error-tracking surface. Sentry's server-side SDK captures IPs, user context, headers, cookies, query strings, and request bodies by default when sendDefaultPii: true. Custom Sentry.setUser() calls often include emails. Stack traces sometimes embed parameter values containing PII. Breadcrumbs accumulate context that may include PII.
  • Structured-logging surface. Pino, Winston, and Bunyan all support redaction config, but it must be explicitly set up. Log call sites often pass entire user/request objects (logger.info({ user })); default-level logging in production may include PII at info/debug levels that were only meant for development.
  • Request-response logging surface. Middleware that logs HTTP requests/responses can leak the most data: POST/PUT bodies (form submissions, JSON payloads with PII), Authorization headers, session cookies, and query strings.

Sentry IP capture: the headline concern

Sentry's server-side SDK captures req.ip by default when sendDefaultPii: true — and sendDefaultPii: true is the master switch that also enables capture of user context, headers, cookies, and query strings. For a project subject to GDPR, this is a default-on PII collection that should be explicitly opted out of (or scoped via a beforeSend hook) unless IP addresses are operationally required (fraud detection, geofencing). The error-tracking agent flags sendDefaultPii: true as 🔴 LEAK when the project handles declared PII — the same headline-finding pattern other masking audits use for their most consequential default-on setting.

Severity semantics

Audit 🔴🟠🟢 here means LEAK / AT RISK / BEST PRACTICE. This is distinct from review severity (🔴 blocking / 🟠 should-fix / 🟢 nice-to-have) and from the other audits' severity glossaries. Same glyphs, different semantics — severity meaning is context-bound.

Glyph Logging-masking audit meaning Review meaning
🔴 LEAK — PII actually leaks to error tracking or logs (e.g. sendDefaultPii: true, logger.info logs a PII object, middleware logs the request body) Blocking — stops pipeline
🟠 AT RISK — potential leak: masking-config gaps, dynamic log content that may contain PII, a beforeSend that may not handle all cases Should-fix — strong recommendation
🟢 BEST PRACTICE — defense-in-depth: more granular redaction, sampled error tracking, log-level appropriateness Nice-to-have — optional improvement

A finding is only 🔴 LEAK when PII demonstrably reaches a telemetry destination. A static-analysis suspicion (dynamic content, complex beforeSend, runtime mutation) is 🟠 AT RISK with manual_review_required: true — never 🔴.

When to use this skill

  • "audit Sentry masking", "check logging PII", "IP masking review", "run the logging masking audit"
  • /pharn-logging-masking-audit
  • Before deploying Sentry (especially the server-side SDK)
  • When adding structured logging (Pino / Winston / Bunyan)
  • When introducing request-logging middleware
  • Quarterly, alongside the broader /pharn-privacy-audit
  • After a near-miss leak via logs or error tracking (post-mortem)

The audit pipeline

Agent assumptions (applies to every sub-agent spawned by this audit):

  • All tools are functional and will work without error. Do not test tools or make exploratory calls. Make sure this is clear to every sub-agent that is launched.
  • Only call a tool if it is required to complete the task. Every tool call should have a clear purpose.
1. DISCOVER     — gather inputs: constitution P1 (Privacy by Default), all features/*/PLAN.md
                  ## Compliance PII inventories, pharn.config.json, Sentry init (sentry*.* and
                  instrumentation*.*), logger setup (logger*.*), middleware files, and all source
                  for log call sites. Detect which surfaces are present; degrade gracefully when
                  inputs are missing and record which agents will run degraded.

2. AGENTS       — spawn the 3 agents in parallel (run_in_background: true), subject to --scope:
                  • error-tracking            (sonnet)
                  • structured-logging        (sonnet, reuses privacy-shield)
                  • request-response-logging  (sonnet, reuses privacy-shield)
                  --scope limits to a single surface. --quick degrades sonnet to haiku (rarely useful).

3. CONSOLIDATE  — collect findings from all agents. Dedup within-run on (agent + type + file + line);
                  when two findings share file+line+type, keep the higher severity. Then collapse any
                  findings that still share (file + line) within one agent into a single finding: keep
                  the highest severity and fold the secondary concern into its description rather than
                  emitting a second finding (e.g. a PII object logged at info level surfaces once as
                  logs-pii-object with the level noted — never also as logs-pii-at-info-level).
                  Severity-rank. Record which agents were skipped (surface not applicable) or errored.

4. REPORT       — write .claude/audits/logging-masking-<YYYY-MM-DD>.md using the structured template
                  (templates/logging-masking-report.template.md): telemetry stack overview, key
                  configuration table, findings by severity, a manual-review section, and a quick
                  remediation cheat sheet. If --quick, prepend the quick-mode warning prominently.

5. SUMMARIZE    — output a one-screen summary: counts per severity (🔴 / 🟠 / 🟢), the top three
                  concerns by remediation priority with file/line pointers, whether Sentry
                  sendDefaultPii is true, and a link to the full report.

--scope flag

  • --scope all (default) — run all three agents per surface detection.
  • --scope error-tracking — run only the error-tracking agent.
  • --scope logging — run only the structured-logging agent.
  • --scope request — run only the request-response-logging agent.

--features flag

Limits the audit to one or more feature modules — scopes call-site scanning and PII-inventory reconciliation to the named features' directories (features/<name>/) and their PLAN.md ## Compliance sections. Accepts a comma-separated list (e.g. --features auth,billing). Default: all features. Useful for a fast re-audit of just the surface you changed.

--quick mode

Degrades the sonnet agents to haiku for a cheaper dev-time spot-check. Rarely useful here — all three agents are already sonnet (mechanical classification work), so the savings are small and the quality loss on call-site judgment is not worth it on a real audit.

The report header will carry this warning when --quick is set:

⚠️ Quick mode used (sonnet agents degraded to haiku). This report is NOT suitable for privacy attestation. Use it as a development feedback loop only.

Failure modes (the audit never hard-fails)

  • No error-tracking tool detectederror-tracking agent reports "no error-tracking tool detected (looked for Sentry / Bugsnag / Rollbar / Honeybadger init) — audit not applicable for this surface." Other agents continue.
  • No structured logger detectedstructured-logging agent reports "no structured logger detected — raw console calls scanned (if any)." Continues.
  • No request-logging middleware detectedrequest-response-logging agent reports "no request-logging middleware detected." Continues.
  • No declared PII inventory in any feature plan → all agents run in degraded mode (privacy-shield-only detection, no inventory comparison); flagged prominently in the report (declared_pii_inventory_present: false).
  • A Sentry.init.beforeSend function with complex/dynamic logic → flagged for manual review; the audit cannot always determine what beforeSend actually masks.
  • An agent errors → recorded in the report's agent execution log; the other agents complete. A single agent error never hard-fails the audit.

Standing audit-finding schema

Every agent emits findings in this shape. Implementers must not invent alternate schemas — the orchestrator consolidates on this contract.

- id: "<AGENT_PREFIX>-<n>" # ERR-1, LOG-2, REQ-3 — sequential within a run
  agent: "error-tracking | structured-logging | request-response-logging"
  surface: "error-tracking | logging | request-logging"
  tool: "sentry | bugsnag | rollbar | honeybadger | pino | winston | bunyan | console | morgan | next-middleware | custom"
  severity: "🔴 LEAK | 🟠 AT RISK | 🟢 BEST PRACTICE"
  type: "<slug>" # stable kebab-case identity, e.g. send-default-pii-true, set-user-with-pii, logs-pii-object
  tool_rule_ref: "<the config option or attribute>" # e.g. "Sentry.init.sendDefaultPii", "pino.redact", "Sentry.beforeSend"
  gdpr_ref: "<Art. | null>" # e.g. "GDPR Art. 5(1)(f)", "GDPR Art. 32"
  file: "<path | null>"
  line: <int | null>
  detected_pii_category: "<from privacy-shield: email, phone, ip, etc. | null>"
  destination: "<where the PII ends up — sentry.io / log-aggregator / null>"
  description: "<what's wrong>"
  evidence: "<code/config snippet supporting the finding>"
  user_impact: "<what kind of PII leaks and to which destination>"
  remediation: "<concrete fix — usually a one-line config or call-site change>"
  manual_review_required: <true | false>

What this skill does NOT do

  • Does NOT wire into /pharn-ship. It is standalone and on-demand; /pharn-ship is feature-scope.
  • Does NOT cover analytics. PostHog capture properties and session replay are the scope of /pharn-posthog-masking-audit (the sibling Tier 2 audit) and /pharn-privacy-audit's telemetry auditor.
  • Does NOT use review severity semantics (blocking / should / nice). Audit severity here is LEAK / AT RISK / BEST PRACTICE.
  • Does NOT re-implement PII detection. The structured-logging and request-response-logging agents reuse privacy-shield's detection via processPrompt().
  • Does NOT silence findings that overlap with /pharn-privacy-audit's telemetry auditor. This is the focused deep audit; surfacing the same issue with tool-specific guidance is the value-add.
  • Does NOT auto-fix masking config. Remediation is paste-ready; the human applies it (disabling IP capture or changing redaction can have operational tradeoffs the audit cannot fully judge).
  • Does NOT pretend to verify a dynamic beforeSend, dynamic log content, or runtime config mutations. These are flagged for manual review with a clear reason.
  • Does NOT mark a finding as 🔴 LEAK on a static-analysis suspicion only — that is 🟠 AT RISK with manual_review_required: true.
  • Does NOT expand v1 scope beyond error tracking + structured logging + request logging. Log aggregation tooling, retention policies, transport TLS, and custom logging libraries are deferred.
  • Does NOT include any banned language from CLAUDE.md §11.
Install via CLI
npx skills add https://github.com/pharn-dev/pharn-oss --skill pharn-logging-masking-audit
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator