Skip to content

Security

claude-telemetry is designed with security as a priority. No API keys are exposed in the frontend, all data access requires authentication, and the architecture follows zero-trust principles.

Authentication Flow

claude-telemetry uses magic link authentication powered by Supabase Auth:

  1. User enters their email on the login page
  2. Supabase sends a one-time magic link to that email
  3. Clicking the link authenticates the user and creates a session
  4. Sessions are stored in HTTP-only cookies with secure flags

Email Whitelist

Only pre-approved emails can log in. The whitelist is stored as a Cloudflare Pages secret (ALLOWED_EMAILS), never in the frontend code.

To add a new user:

bash
npx wrangler pages secret put ALLOWED_EMAILS
# Enter comma-separated list: you@example.com,teammate@example.com

Worker Proxy

The Cloudflare Pages Functions sit between the dashboard and Supabase, acting as a security proxy:

Browser  ──▶  Pages Functions (has secrets)  ──▶  Supabase
         ◀──                                  ◀──

What the proxy does:

  • Validates the user's auth session
  • Injects the Supabase service key into requests
  • Enforces the email whitelist
  • Strips sensitive headers before returning responses

What the browser never sees:

  • Supabase service role key
  • Supabase URL (proxied through the Worker)
  • Direct database access

Row-Level Security (RLS)

Supabase's Row-Level Security is enabled on the usage_data table. Even if someone obtained a key, RLS policies restrict what data they can access:

sql
-- Only authenticated users can read
CREATE POLICY "Authenticated users can read"
  ON usage_data FOR SELECT
  USING (auth.role() = 'authenticated');

-- Only the agent service role can insert
CREATE POLICY "Service role can insert"
  ON usage_data FOR INSERT
  WITH CHECK (auth.role() = 'service_role');

Agent Authentication

Each agent authenticates with Supabase using an API key configured during setup. This key:

  • Is stored locally in ~/.claude-tracker/config.json (file permissions: owner-only)
  • Has limited permissions (insert-only on usage_data)
  • Is unique per machine (you can revoke one without affecting others)

Data Privacy

claude-telemetry collects usage metadata only:

CollectedNot Collected
Token counts (input/output/cache)Prompt content
Cost in USDResponse content
Model nameFile contents
Session timestampsCode or conversation text
Project directory pathEnvironment variables
Machine identifierUser credentials

The project directory path is the only potentially identifying field. You can exclude specific directories by adding them to the agent's ignore list in config.json.

Self-Hosted

All components are self-hosted on your own accounts:

  • Supabase: Your project, your database, your data
  • Cloudflare: Your account, your Workers, your Pages
  • Agent: Runs on your machines, reads your local files

No data is ever sent to claude-telemetry's infrastructure. There is no claude-telemetry cloud service.

Released under the MIT License.