Open AnalyticsOpen Analytics
Home/Documentation

Security

The default schema is optimized for self-hosted demos and quick setup. Before exposing a public instance, review these risks and mitigations.

Supabase anon key in the browser

The standard embed snippet includes the site project's anon key. Anyone can read it from your page source. With default RLS, that key can:

  • Insert events for valid site_key values
  • Read all events (dashboard policy allows select for anon)

Mitigations:

  • Use data-endpoint and a server route that validates payloads instead of exposing the publishable key in HTML.
  • Tighten RLS: remove broad select for anon; authenticate dashboard users and use user-scoped policies.
  • Restrict inserts by IP or rate limit at the edge.

App vs analytics projects

The app Supabase project (`.env`) should only hold accounts and site bookmarks. Your analytics Supabase project holds events — tighten anon policies there before high traffic.

Bot traffic

The tracker skips common bots via User-Agent regex. This does not stop:

  • Bots that mimic a normal browser
  • Direct API inserts into events
  • Historical bot data already stored

Server-side filtering would require storing user_agent or an is_bot flag and excluding those rows in aggregations.

Privacy

  • Visitor identification uses a fingerprint + localStorage — disclose this in your privacy policy where required (e.g. GDPR).
  • Optional data-do-not-track="true" respects browser DNT when enabled.
  • identify() can attach a logged-in user id; treat distinct_id as personal data if it maps to accounts.
  • Geo uses approximate location from IP via your geo endpoint — document retention.

Production checklist

  1. Replace open RLS with auth-backed policies.
  2. Keep app and analytics Supabase keys scoped; rotate if leaked.
  3. Set NEXT_PUBLIC_APP_URL to HTTPS production origin.
  4. Enable Supabase rate limiting / WAF as needed.
  5. Rotate anon/service keys if leaked.
  6. Back up per-site Supabase projects regularly.