SE

sentry-data-handling

Implements PII scrubbing, data retention, and GDPR controls for Sentry error monitoring.

Install

mkdir -p .claude/skills/sentry-data-handling && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/8963" && unzip -o skill.zip -d .claude/skills/sentry-data-handling && rm skill.zip

Installs to .claude/skills/sentry-data-handling

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Configure GDPR-compliant data handling, PII scrubbing, and data
63 charsno explicit “when” trigger
Advanced

Key capabilities

  • Configure client-side PII scrubbing with `beforeSend` hooks
  • Implement server-side data scrubbing rules
  • Anonymize IP addresses in Sentry events
  • Handle data subject deletion requests via API
  • Implement SOC 2 audit controls

How it works

This skill configures client-side PII scrubbing using `beforeSend` hooks to strip sensitive data from headers, request bodies, error messages, and user context before events leave the application. It also covers server-side scrubbing and GDPR compliance.

Inputs & outputs

You give it
Sentry SDK configuration, `beforeSend` function, sensitive data patterns
You get back
Sentry events with PII scrubbed, verification test results

When to use sentry-data-handling

  • Implementing PII scrubbing
  • Configuring GDPR compliance
  • Setting data retention policies

About this skill

Sentry Data Handling

Configure PII scrubbing, GDPR compliance, data retention, and audit controls for Sentry. This skill covers client-side filtering with beforeSend, server-side scrubbing rules, data subject erasure via API, and SOC 2 compliance patterns.

Overview

Sentry captures error context that often contains personally identifiable information (PII) — emails in stack traces, credit card numbers in request bodies, IP addresses in headers. Production deployments must scrub this data at two layers: client-side via beforeSend hooks (before data leaves the application) and server-side via Sentry's built-in Data Scrubber (defense in depth). GDPR requires additional controls: consent-based initialization, data subject deletion endpoints, and a signed Data Processing Agreement. This skill implements all three layers with TypeScript and Python examples, plus verification tests to prove scrubbing works end-to-end.

Prerequisites

  • Sentry SDK v8 installed and initialized (@sentry/node or sentry-sdk)
  • Sentry project with Admin or Owner role (required for Security & Privacy settings)
  • Compliance requirements documented (GDPR, HIPAA, PCI-DSS, or SOC 2)
  • Auth token with project:write and org:admin scopes for API operations
  • Data Processing Agreement signed at https://sentry.io/legal/dpa/ (GDPR requirement)

Instructions

Step 1 — Client-Side PII Scrubbing with beforeSend

The first defense layer prevents PII from leaving your application. Configure beforeSend, beforeSendTransaction, and beforeBreadcrumb hooks during SDK initialization:

import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: process.env.SENTRY_DSN,

  // CRITICAL: disable automatic PII collection
  // When false, Sentry will NOT capture IP addresses, cookies, or user-agent
  sendDefaultPii: false,

  beforeSend(event) {
    return scrubEvent(event);
  },

  beforeSendTransaction(event) {
    return scrubEvent(event);
  },

  beforeBreadcrumb(breadcrumb) {
    if (breadcrumb.data) {
      const sensitiveKeys = ['password', 'token', 'secret', 'api_key', 'authorization'];
      for (const key of sensitiveKeys) {
        if (breadcrumb.data[key]) {
          breadcrumb.data[key] = '[REDACTED]';
        }
      }
    }
    return breadcrumb;
  },
});

Implement the scrubEvent function to strip PII from headers, request bodies, error messages, and user context:

function scrubEvent(event: Sentry.Event): Sentry.Event | null {
  // Strip sensitive headers
  if (event.request?.headers) {
    const redactHeaders = ['Authorization', 'Cookie', 'X-Api-Key', 'X-Auth-Token'];
    for (const header of redactHeaders) {
      delete event.request.headers[header];
    }
  }

  // Scrub request body fields
  if (event.request?.data) {
    const data = typeof event.request.data === 'string'
      ? safeJsonParse(event.request.data)
      : event.request.data;

    if (data && typeof data === 'object') {
      scrubObject(data as Record<string, unknown>);
      event.request.data = JSON.stringify(data);
    }
  }

  // Scrub PII patterns from error messages
  if (event.exception?.values) {
    for (const exc of event.exception.values) {
      if (exc.value) {
        exc.value = scrubPiiPatterns(exc.value);
      }
    }
  }

  // Reduce user context to anonymous ID only
  if (event.user) {
    event.user = { id: event.user.id };
  }

  return event;
}

function scrubObject(obj: Record<string, unknown>): void {
  const sensitiveKeys = [
    'password', 'passwd', 'secret', 'token', 'api_key', 'apiKey',
    'ssn', 'social_security', 'credit_card', 'cc_number', 'cvv',
    'email', 'phone', 'address', 'dob', 'date_of_birth',
  ];

  for (const key of Object.keys(obj)) {
    if (sensitiveKeys.some(sk => key.toLowerCase().includes(sk))) {
      obj[key] = '[REDACTED]';
    } else if (typeof obj[key] === 'string') {
      obj[key] = scrubPiiPatterns(obj[key] as string);
    } else if (typeof obj[key] === 'object' && obj[key] !== null) {
      scrubObject(obj[key] as Record<string, unknown>);
    }
  }
}

function scrubPiiPatterns(str: string): string {
  return str
    .replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, '[EMAIL]')
    .replace(/\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{1,7}\b/g, '[CC_NUMBER]')
    .replace(/\b\d{3}-\d{2}-\d{4}\b/g, '[SSN]')
    .replace(/\b(\+1)?[\s-]?\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}\b/g, '[PHONE]');
}

function safeJsonParse(str: string): unknown {
  try { return JSON.parse(str); } catch { return null; }
}

Python equivalent — use the same before_send pattern:

import sentry_sdk
import re

def scrub_event(event, hint):
    """Remove PII from Sentry events before transmission."""
    # Strip sensitive headers
    request = event.get("request", {})
    headers = request.get("headers", {})
    for key in ["Authorization", "Cookie", "X-Api-Key"]:
        headers.pop(key, None)

    # Scrub user context to anonymous ID
    user = event.get("user")
    if user:
        event["user"] = {"id": user.get("id")}

    # Scrub PII patterns from exception messages
    for exc in event.get("exception", {}).get("values", []):
        if exc.get("value"):
            exc["value"] = re.sub(
                r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
                "[EMAIL]", exc["value"]
            )

    return event

sentry_sdk.init(
    dsn=os.environ["SENTRY_DSN"],
    send_default_pii=False,
    before_send=scrub_event,
    traces_sample_rate=0.1,
)

Step 2 — Server-Side Data Scrubbing and IP Anonymization

Server-side scrubbing acts as defense in depth. Configure in Project Settings > Security & Privacy:

  1. Enable Data Scrubber — automatically redacts values matching common PII field names (password, token, secret)
  2. Custom Sensitive Fields — add project-specific fields:
    • password, secret, token, api_key, ssn, credit_card, cvv, authorization
  3. Safe Fields — fields that must never be scrubbed:
    • transaction_id, order_id, request_id, trace_id
  4. Scrub IP Addresses — enable to remove client IPs from all events
  5. Scrub Credit Cards — detect and remove card number patterns

For advanced regex-based rules, navigate to Project Settings > Security & Privacy > Advanced Data Scrubbing:

# Remove credit card patterns from all string fields
[Remove] [Regex: \d{4}-\d{4}-\d{4}-\d{4}] from [$string]

# Remove email addresses everywhere
[Remove] [Regex: \b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b] from [$string]

# Remove SSN patterns
[Remove] [Regex: \b\d{3}-\d{2}-\d{4}\b] from [$string]

# Mask passwords in request bodies
[Mask] [Password] from [extra.request_body]

# Replace credit card data everywhere with placeholder
[Replace] [Credit card] with [REDACTED] from [**]

Data forwarding — if forwarding events to external systems (Splunk, BigQuery), apply the same scrubbing rules at the destination. Configure forwarding in Project Settings > Data Forwarding.

Data retention — configure in Organization Settings > Subscription > Data Retention:

PlanDefault retentionMaximum retention
Developer30 days30 days
Team90 days90 days
Business90 days365 days
Enterprise90 daysCustom

Step 3 — GDPR Compliance and Data Subject Requests

Right to be Informed — document Sentry usage in your privacy policy. Disclose what data is collected (stack traces, device info, anonymized user IDs) and the legal basis (legitimate interest in application reliability).

Consent-based initialization — for strict GDPR compliance, gate Sentry on user consent:

function initSentryWithConsent(hasConsent: boolean): void {
  if (!hasConsent) {
    // Do not initialize Sentry — no data sent
    return;
  }

  Sentry.init({
    dsn: process.env.SENTRY_DSN,
    sendDefaultPii: false,
    beforeSend: scrubEvent,
  });
}

Right to Erasure (Article 17) — delete user data via the Sentry API:

# Delete all events for a specific issue
curl -X DELETE \
  -H "Authorization: Bearer ${SENTRY_AUTH_TOKEN}" \
  "https://sentry.io/api/0/projects/${SENTRY_ORG}/${SENTRY_PROJECT}/issues/${ISSUE_ID}/" \
  || { echo "ERROR: Deletion failed — verify auth token has project:admin scope"; exit 1; }
// Programmatic deletion for data subject requests
async function handleDeletionRequest(userId: string): Promise<void> {
  const org = process.env.SENTRY_ORG;
  const project = process.env.SENTRY_PROJECT;
  const token = process.env.SENTRY_AUTH_TOKEN;

  // Search for issues containing user data
  const searchRes = await fetch(
    `https://sentry.io/api/0/projects/${org}/${project}/issues/?query=user.id:${userId}`,
    { headers: { Authorization: `Bearer ${token}` } }
  );

  if (!searchRes.ok) {
    throw new Error(`Search failed: ${searchRes.status} ${searchRes.statusText}`);
  }

  const issues = await searchRes.json();

  // Delete each matching issue
  for (const issue of issues) {
    const deleteRes = await fetch(
      `https://sentry.io/api/0/projects/${org}/${project}/issues/${issue.id}/`,
      { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } }
    );

    if (!deleteRes.ok) {
      throw new Error(`Deletion failed for issue ${issue.id}: ${deleteRes.status}`);
    }
  }

  console.log(`Deleted ${issues.length} issues for user ${userId}`);
}

Audit log access — Business and Enterprise plans provide audit logs at Organization Settings > Audit Log. Export via API for SOC 2 evidence:

# Retrieve audit log entries (requires org:admin scope)
curl -H "Authorization: Bearer ${SENTRY_AUTH_TOKEN}" \
  "https://sentry.io/api/0/organizations/${SENTRY_ORG}/audit-logs/" \
  || echo "ERROR: Audit logs require Business or Enterprise plan"

SOC 2 compliance checklist:

  1. Enable audit logging (Business/Enterprise plan required)
  2. Co

Content truncated.

Prerequisites

Sentry SDK v8 installed and initializedSentry project with Admin or Owner roleCompliance requirements documented (GDPR, HIPAA, PCI-DSS, or SOC 2)Auth token with `project:write` and `org:admin` scopes for API operations

How it compares

This skill automates the configuration of multi-layered PII scrubbing and GDPR compliance in Sentry, unlike manually implementing each data handling step.

Compared to similar skills

sentry-data-handling side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
sentry-data-handling (this skill)025dCautionAdvanced
sentry-multi-env-setup225dReviewIntermediate
security-header-generator59moCautionIntermediate
backend-security-coder244moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

sentry-multi-env-setup

jeremylongshore

Configure Sentry across multiple environments. Use when setting up Sentry for dev/staging/production, managing environment-specific configurations, or isolating data. Trigger with phrases like "sentry environments", "sentry staging setup", "multi-environment sentry", "sentry dev vs prod".

210

security-header-generator

Dexploarer

Generates security HTTP headers (CSP, HSTS, CORS, etc.) for web applications to prevent common attacks. Use when user asks to "add security headers", "setup CSP", "configure CORS", "secure headers", or "HSTS setup".

599

backend-security-coder

sickn33

Expert in secure backend coding practices specializing in input validation, authentication, and API security. Use PROACTIVELY for backend security implementations or security code reviews.

2446

security-best-practices

openai

Perform language and framework specific security best-practice reviews and suggest improvements. Trigger only when the user explicitly requests security best practices guidance, a security review/report, or secure-by-default coding help. Trigger only for supported languages (python, javascript/typescript, go). Do not trigger for general code review, debugging, or non-security tasks.

732

dependency-auditor

alirezarezvani

Check dependencies for known vulnerabilities using npm audit, pip-audit, etc. Use when package.json or requirements.txt changes, or before deployments. Alerts on vulnerable dependencies. Triggers on dependency file changes, deployment prep, security mentions.

16

command-injection-testing

Ed1s0nZ

命令注入漏洞测试的专业技能和方法论

13

Search skills

Search the agent skills registry