Clerion
  • Get started
  • Pricing
  • Compare
Start free
  • Get started
  • Pricing
  • Compare
Start free
Trust & compliance
  • Privacy Policy
  • Terms of Service
  • GDPR Compliance
  • Schrems II Compliance
  • ePrivacy Compliance
  • PECR Compliance
  • COPPA Compliance
  • CCPA Compliance
  • Our Data Journey
  • Security

Security

We use managed infrastructure providers to deliver Clerion. This page explains the security posture of every service we rely on: what they provide by default, and what we add on top. Every claim below is backed by our actual production architecture.

We are an EU-first platform. Our Node.js backend runs on Railway in the Netherlands (eu-west). Our PostgreSQL database runs on Supabase in Frankfurt (AWS eu-central-1). Visitor personal data (specifically IP addresses) is pseudonymised in-memory on EU infrastructure and is never forwarded to any US-based service in identifiable form. See our Schrems II compliance page and data journey for the full analysis.


Service providers

Railway (Netherlands, EU)

Railway hosts our Node.js/Express backend on EU infrastructure in the Netherlands (eu-west region). Railway provides:

  • Physical and network security: hosted on enterprise-grade cloud infrastructure with managed DDoS protection and network isolation
  • TLS in transit: all connections to our backend are encrypted; Railway terminates TLS at the edge
  • Environment variable management: secrets (JWT secrets, database credentials, API keys) are stored as encrypted environment variables, not committed to source control
  • Automatic restarts and high availability: the backend service is monitored and restarted automatically in the event of failure
  • EU data residency: the eu-west region ensures that all processing occurs within the European Union

Railway's security documentation: railway.app/security

Clerion's additional measures on Railway:

  • Production access is restricted to named engineers. No shared credentials.
  • All secrets are managed as environment variables and rotated when personnel changes occur.
  • No raw IP addresses are written to Railway logs. Our logging configuration explicitly omits personal data.
  • The trust proxy setting is configured to 1 (single-hop trusted proxy) rather than unrestricted, preventing IP spoofing via arbitrary X-Forwarded-For headers.

Supabase (Frankfurt, AWS eu-central-1)

Supabase hosts our PostgreSQL database and provides our authentication infrastructure (Postgres Row Level Security). Supabase's security posture includes:

  • SOC 2 Type 2 certification
  • Encryption at rest: all data is encrypted using AES-256
  • Encryption in transit: TLS 1.2+ enforced for all connections
  • Row Level Security (RLS): Supabase's native RLS is enabled on every analytics table

Supabase's security documentation: supabase.com/security

Clerion's additional measures on Supabase:

Row Level Security on every table. We enable RLS across all data tables and enforce tenant isolation via scoped client credentials. Each API request runs under a Supabase client scoped to the authenticated user's ID: a user cannot read or write another user's data even if they somehow bypassed application-layer checks. Tables with RLS enabled include: analytics_events, website_setups, users, console_errors, ai_chat_sessions, ai_chat_messages, ai_usage_log, ai_response_cache, revoked_refresh_tokens.

Database credentials are not exposed to the frontend. The browser-side SDK has no direct database access whatsoever. All database operations happen server-side via authenticated API routes.

Only de-identified data is stored at rest. The analytics_events table contains no raw IP addresses, only HMAC-SHA256 hashes and derived country codes. Even unrestricted database access would expose no personal data in its original form.


IPLocate.io (EU endpoint)

IPLocate.io provides IP geolocation. We use their EU-only API endpoint (https://eu-api.iplocate.io/) exclusively. IPLocate:

  • Routes our queries to EU-located servers
  • Does not retain IP addresses beyond the duration of each API call
  • Operates under a signed Data Processing Agreement with EU Standard Contractual Clauses, available at iplocate.io/legal/dpa and incorporated into their Terms of Service

Clerion's additional measures:

  • Geo lookup results are cached in-memory for 24 hours to minimise the number of IPs transmitted to IPLocate and to stay within our API quota.
  • The raw IP address is discarded immediately after the lookup completes. It is never written to the database or to any log file.
  • Lookups skip private, loopback, and link-local IPs (RFC 1918, RFC 3927). These are not forwarded to IPLocate at all.

Anthropic

Anthropic's Claude powers Clerion's AI analytics features. Anthropic:

  • Holds SOC 2 Type 2 certification
  • Operates under a Data Processing Addendum (DPA) available at anthropic.com/legal/data-processing-addendum
  • Prohibits using customer data for model training under the DPA

Clerion's additional measures:

No personal data is sent to Anthropic. Before any data is passed to Claude, our backend builds an aggregated statistical context from Supabase queries: counts, percentages, ranked lists, and time-series summaries. Claude never receives individual event rows, IP hashes, session IDs, or visitor identifiers. See the AI layer section of our data journey for the exact structure of what is transmitted.

Prompt injection protection. Visitor-controlled strings (page titles, meta descriptions, site headlines) that are embedded in AI prompts are sanitised before forwarding: known injection patterns are stripped and string lengths are capped.


Application security

HTTPS everywhere

All connections to the Clerion dashboard and API are served over HTTPS. HTTP is not supported. TLS is terminated at Railway's edge layer.

HTTP security headers

We use Helmet.js to set security-relevant HTTP response headers on every API response, including:

  • Content-Security-Policy
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Strict-Transport-Security (HSTS)
  • Referrer-Policy

CSRF protection (double-submit cookie pattern)

State-changing requests from the dashboard (POST, PUT, DELETE, PATCH) are protected against Cross-Site Request Forgery. Our server issues a cryptographically random XSRF-TOKEN cookie (64 hex characters, SameSite=Lax, Secure in production). The browser must echo this token in the X-XSRF-TOKEN request header. The two values are compared on the server; mismatches are rejected with 403 Forbidden.

The tracking API (/api/v1/track) is exempt from CSRF validation: it is authenticated by a per-site API key, not by session cookies.

JWT authentication with short-lived access tokens

Authentication uses two-token architecture:

  • Access tokens: 15-minute lifetime, signed with ACCESS_TOKEN_SECRET, verified on every authenticated request
  • Refresh tokens: 7-day lifetime, signed with a separate REFRESH_TOKEN_SECRET, used only to issue new access tokens

Refresh token revocation is tracked in the revoked_refresh_tokens table with a unique JWT ID (jti) per token. On logout, the refresh token's jti is recorded; subsequent refresh attempts using that token are rejected. Revoked tokens are cleaned up automatically on expiry.

Access tokens are verified with explicit issuer validation (iss: 'clerion'). Expired tokens return 401 with a needsRefresh flag rather than leaking error details.

Password hashing

User passwords are hashed with bcrypt at cost factor 12. This requires approximately 250 ms per hash operation on a 2024-era server, making offline brute-force of a stolen hash infeasible. Passwords are never stored in plain text and are never logged. We cannot recover a user's password, only reset it.

Rate limiting

Three separate rate limiters protect different surface areas:

Endpoint groupWindowLimitKey
Auth endpoints (/auth/*)15 minutes10 requestsPer IP
Tracking ingestion (/api/v1/track)1 minute300 requestsPer API key (fallback: IP)
Dashboard API (/analytics/*)1 minute120 requestsPer IP

The authentication limiter is strict (10 attempts per 15-minute window) to prevent credential stuffing. The tracking limiter uses the API key as the primary key so that legitimate high-traffic sites are not throttled by sharing a source IP with other services.

API key validation

Every tracking request must carry a valid x-api-key header. The API key is validated against the website_setups table before any event processing occurs. Requests with missing, invalid, or revoked keys are rejected with 401 before any IP hashing, geo lookup, or database write takes place.

Body size limits

API request bodies are capped server-side:

  • General API routes: 50 KB
  • Tracking ingestion routes: 100 KB (to accommodate batched event payloads)
  • Batch event ingestion: maximum 100 events per request

Oversized requests are rejected before body parsing completes.

Error handling

Our centralised error handler never exposes internal error details (stack traces, database error messages, internal paths) in production API responses. All 5xx errors return the generic message "An unexpected error occurred." The full error detail is logged server-side only.

Input sanitisation

Metadata submitted via the tracking SDK is sanitised before storage to prevent injection of oversized payloads or malformed data. Page paths and User-Agent strings are capped at 2,048 and 512 characters respectively.


What we don't store

We reduce risk by not storing data we do not need. Specifically:

  • No raw IP addresses in the database or in logs
  • No raw User-Agent strings stored at rest
  • No cookies set by the tracking script
  • No payment card data: billing is handled by our payment processor; we never see or store card numbers
  • No passwords in plain text, ever

Responsible disclosure

If you discover a security vulnerability in Clerion AI, please contact us at hello@getclerion.com before disclosing it publicly. We will acknowledge your report promptly, investigate, and work to resolve confirmed issues as quickly as possible.

Last updated May 2026For questions about our privacy or data practices, contact our team at hello@getclerion.com
Clerion

Clerion reads your analytics for you and tells you what to do, in plain English. Cookie-free, privacy-first, and live in about a minute.

We don’t have an ad budget. If Clerion helps you, telling a friend does more for us than any campaign could.

© 2026 Clerion

Get started

  • Get started
  • Pricing
  • Start free

Learn

  • Blog
  • Podcast
  • Help Centre
  • API documentation

Our software

  • About us
  • vs Google Analytics
  • vs Mixpanel
  • vs Plausible
  • vs Matomo
  • vs Fathom
  • vs Cloudflare

Compliance

  • GDPR
  • Schrems II
  • ePrivacy
  • PECR
  • COPPA
  • CCPA
  • Our Data Journey
  • Security

Legal

  • Privacy
  • Terms
  • Contact
  • Affiliates
  • Changelog
  • Status
  • Roadmap
  • Sitemap