Security & Privacy

Databuddy is built with privacy-first principles and enterprise-grade security. This guide covers what we do to protect your data and how to configure privacy settings for your users.

Privacy-First Design

What We Don't Collect by Default

  • No Personal Information - Names, emails, phone numbers, and addresses are never collected unless you explicitly send them with the opt-in identify() API
  • No Cookies for Tracking - Only local storage for anonymous IDs
  • No Cross-Site Tracking - Each site is isolated
  • No Cross-Site Fingerprinting - Device data is used for on-site analytics only, and Global Privacy Control and Do Not Track signals are honored by default
  • No Raw IP Addresses - Used for location (country/region), then only a truncated salted hash is retained

What We Do Collect

  • Anonymous Usage Data - Page views, clicks, performance metrics
  • Session Information - Anonymous session IDs with 30-minute timeouts
  • Technical Data - Browser type, screen size, performance metrics
  • Location Data - Country and region only (from IP, then IP discarded)

Data Protection

Anonymous by Default

javascript
// All users get anonymous IDs - no personal data
{
  anonymousId: "anon_abc123...",      // Random UUID
  sessionId: "sess_xyz789...",        // Session identifier
  event: "page_view",                 // What happened
  path: "/dashboard",                 // Where it happened
  // No names, emails, or personal data
}

Local Data Storage

  • Anonymous ID - Stored in localStorage and sent with events. Depending on your site's anonymizeVisitorIds setting, it is salted and hashed server-side with a daily-rotating salt before storage
  • Session Data - Temporary sessionStorage, clears on browser close
  • No Cookies - We don't use tracking cookies
  • User Control - Easy to clear all data, and window.databuddyOptOut() stops collection entirely

Privacy Compliance

GDPR Compliance by Design

Lawful Basis: Legitimate interest for website analytics

Databuddy is anonymous by default and avoids analytics-specific consent friction when your configuration and jurisdiction allow cookieless measurement:

  • No Personal Data by Default - Only anonymous usage statistics unless you opt in to identify()
  • No Cookies Used - A localStorage anonymous ID only, with no cross-site tracking
  • Anonymous by Default - Individual users are not identified unless your site sends identity data
  • Server-Side Anonymization - Visitor IDs are salted and hashed where anonymization applies

If you use identify() to attach names, emails, or traits to profiles, that data is personal data you control: reflect it in your privacy policy and consent flow. Whether a consent banner is required always depends on your configuration, what you send, and your jurisdiction's rules; when in doubt, ask your counsel.

tsx
import { Databuddy } from "@databuddy/sdk/react";

function App() {
  return (
    <>
      {/* Anonymous, cookieless measurement */}
      <Databuddy
        clientId="your-client-id"
        trackWebVitals
      />
    </>
  );
}

Why many sites can run Databuddy without an analytics consent banner:

  • Anonymous data only, no cross-site tracking
  • No personal information in the default configuration
  • No advertising or behavioral profiling
  • Legitimate interest is the typical lawful basis for anonymous audience measurement

This changes if you enable identify() or send personal data in event properties: at that point you are processing personal data and your normal consent and privacy-policy obligations apply.

Privacy Controls

Minimal Tracking Setup

Minimal Tracking Setuptsx
// Essential analytics only
<Databuddy
  clientId="your-client-id"
  // Basic page tracking (automatic)
  // Disable everything else
  trackWebVitals={false}
  trackOutgoingLinks={false}
  trackErrors={false}
/>

Development vs Production

Environment Configurationtsx
const isProd = process.env.NODE_ENV === "production";

<Databuddy
  clientId="your-client-id"
  disabled={!isProd} // No tracking in development
  // Production-only features
  trackWebVitals={isProd}
/>;

🔐 Security Features

Domain Protection

  • Domain Verification Required - Only verified domains can send data
  • Origin Validation - Requests validated against registered domains
  • HTTPS Required - All communications encrypted in transit

Access Control Settings

Configure allowed origins and IP addresses to control who can send analytics data to your website.

Allowed Origins

By default, Databuddy only accepts requests from your website's registered domain. To track analytics from third-party services (like Cal.com, embedded widgets, or other integrations), you need to add those domains to your allowed origins.

Access: Open Websites, select your site, then go to Settings → Security.

Default Behavior:

  • Only requests from your registered domain are accepted
  • Requests from other origins are blocked with a 403 error

Supported Formats:

  • Exact domains: cal.com, example.com
  • Wildcard subdomains: *.cal.com (matches app.cal.com, api.cal.com, etc.)
  • Localhost: localhost (for development)
  • Allow all: * (allows any origin - use with caution)

How It Works:

  1. By default, only your registered domain can send analytics data
  2. Add additional origins to allow third-party integrations
  3. Requests from unauthorized origins are blocked with a 403 error

Example Configuration:

Allowed Origins:
- cal.com
- *.cal.com
- localhost

Allowed IP Addresses

Restrict analytics requests to specific IP addresses or IP ranges using CIDR notation.

Supported Formats:

  • Single IPv4: 192.168.1.1
  • Single IPv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • CIDR ranges: 192.168.1.0/24, 10.0.0.0/8

How It Works:

  1. When allowedIps is configured, only requests from those IPs/ranges are accepted
  2. If not configured, all IPs are allowed (standard behavior)
  3. IP addresses are extracted from request headers (cf-connecting-ip, x-forwarded-for, x-real-ip)
  4. Requests from unauthorized IPs are blocked with a 403 error

Example Configuration:

Allowed IPs:
- 192.168.1.1
- 10.0.0.0/8
- 172.16.0.0/12

Use Cases:

  • Internal Tools: Restrict analytics to your office IP range
  • API Integrations: Allow only specific server IPs
  • Development: Limit to your development environment IPs
  • Security: Block suspicious IP ranges

Important: If you configure allowed IPs, make sure to include your production servers and any legitimate sources. Blocking legitimate traffic will prevent analytics collection.

Third-Party Integrations: If you use services like Cal.com, embedded widgets, or other integrations that need to send analytics from their domains, add those domains to your allowed origins.

Data Validation

  • Input Sanitization - All user data cleaned and validated
  • Size Limits - Prevents large payloads and spam
  • Rate Limiting - Protects against abuse

Infrastructure Security

  • Encrypted Transport - All traffic is served over TLS
  • DDoS Protection - Automatic attack mitigation at the edge
  • Application-Layer Encryption - Identity fields such as names and emails support AES-256-GCM encryption at rest
  • Open Source - The full codebase is public and auditable

🛠️ User Privacy Controls (Optional)

Anonymous by Default

In the default configuration Databuddy collects anonymous data only, so there is usually no personal data to delete. If you use identify(), the profiles you create are personal data: handle deletion requests for them, and contact support@databuddy.cc if you need help removing profile data. Either way, you can provide opt-out controls.

Optional Opt-Out Implementation

The tracker ships built-in opt-out helpers. window.databuddyOptOut() stops tracking, clears local state, and persists the preference in localStorage under databuddy_opt_out; window.databuddyOptIn() reverses it.

Optional Opt-Out Componenttsx
function PrivacyControls() {
  const [trackingEnabled, setTrackingEnabled] = useState(true);

  const handleOptOut = () => {
    window.databuddyOptOut();
    setTrackingEnabled(false);
  };

  const handleOptIn = () => {
    window.databuddyOptIn();
    setTrackingEnabled(true);
  };

  return (
    <div>
      <p>
        Analytics helps us improve our website. No personal data is collected.
      </p>

      <label>
        <input
          type="checkbox"
          checked={trackingEnabled}
          onChange={(e) =>
            e.target.checked ? handleOptIn() : handleOptOut()
          }
        />
        Enable anonymous analytics
      </label>
    </div>
  );
}

The anonymous ID itself is stored in localStorage under the did key.

Data Deletion in Practice

  • Anonymous by Default - The default configuration stores no data that identifies individual users, so there is usually nothing to delete
  • Identified Profiles Are Different - Profiles created via identify() contain personal data; deletion requests for them are honored, and support@databuddy.cc can help
  • DNT and GPC Honored - Visitors with Do Not Track or Global Privacy Control enabled are not tracked at all by default

🌐 Global Privacy Settings

Respect Browser Preferences

Respect Browser Privacy Settingsjavascript
// Check Do Not Track setting
const respectDNT = navigator.doNotTrack === "1";

<Databuddy
  clientId="your-client-id"
  disabled={respectDNT} // Respect browser privacy setting
/>;

📋 Privacy Best Practices

1. Be Transparent

Privacy Notice Componenttsx
// Clear privacy notice
function PrivacyNotice() {
  return (
    <div className="privacy-notice">
      <h3>We respect your privacy</h3>
      <p>
        We collect anonymous usage data to improve our website. No personal
        information is collected. You can opt out anytime.
      </p>
      <a href="/privacy-policy">Read our privacy policy</a>
    </div>
  );
}

2. Provide Controls (Optional)

Privacy Dashboard Componenttsx
// Optional privacy dashboard (not required since data is anonymous)
function PrivacyDashboard() {
  return (
    <div>
      <h2>Analytics Preferences</h2>

      <div>
        <h3>Anonymous Data Collection</h3>
        <p>Help us improve our website with anonymous usage statistics.</p>
        <Toggle label="Page views" />
        <Toggle label="Performance metrics" />
        <Toggle label="Error tracking" />
      </div>

      <div>
        <h3>Your Privacy</h3>
        <p>✅ Analytics are anonymous by default</p>
        <p>✅ No cookies are used for tracking</p>
        <p>✅ No cross-site tracking or profiling</p>
        <button onClick={clearLocalData}>Clear local preferences</button>
      </div>
    </div>
  );
}

3. Honor Preferences

Respect User Preferencestsx
// Respect user choices
const privacySettings = getUserPrivacySettings();

<Databuddy
  clientId="your-client-id"
  // Screen views are tracked automatically
  trackWebVitals={privacySettings.allowPerformance}
  trackErrors={privacySettings.allowErrors}
/>

Privacy Policy Should Include:

  • Anonymous analytics are collected via Databuddy
  • No personal information or cookies are used
  • Data is used only for website improvement
  • Optional: How users can opt-out

Cookie Notice:

  • Not required for Databuddy (no cookies used)
  • Only needed if you use other tracking tools

Sample Privacy Policy Text

Analytics: We use Databuddy to collect anonymous website usage statistics
to help us improve our site. No personal information, cookies, or tracking
is used. All data is completely anonymous and cannot identify individual
visitors. Data is processed securely by Databuddy and used only for
understanding website performance and usage patterns.

Minimal Privacy Notice

We collect anonymous usage statistics to improve our website.
No personal data or cookies are used.

🛡️ Implementation Security

Content Security Policy

Content Security Policyhtml
<!-- Add Databuddy to your CSP -->
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' https://cdn.databuddy.cc; 
  connect-src 'self' https://basket.databuddy.cc;"
/>

Secure Configuration

Secure Environment Configurationtsx
// Environment-specific settings
const config = {
  development: {
    clientId: process.env.NEXT_PUBLIC_DATABUDDY_DEV_ID,
    disabled: true, // No tracking in development
  },
  production: {
    clientId: process.env.NEXT_PUBLIC_DATABUDDY_PROD_ID,
    disabled: false,
  },
}[process.env.NODE_ENV];

<Databuddy {...config} />;

🆘 Support & Questions

Privacy Questions

If you have questions about privacy or data handling:

Data Requests

In the default anonymous configuration there is typically no personal data to request. For sites using identify(), or for any question about our data handling, reach out and we will respond promptly:


What's Next?

How is this guide?