Security

Content Security Policy

Every route enforces a strict Content Security Policy. Only whitelisted domains can load scripts or establish connections. Inline scripts are blocked. This prevents cross-site scripting and unauthorized code execution.

Row-level security

Every database table enforces row-level security at the Postgres level. You can only read and write your own data. This is not application-level filtering — it is enforced by the database engine itself, regardless of how the data is queried.

Encryption at rest

Wallet addresses are encrypted using AES-256-GCM before being stored. The encryption key is managed separately from the database and is never exposed in the application codebase or client-side code.

Shared data isolation

Market data like price caches is shared across users but is read-only at the database level. Writes to shared tables go through privileged database functions with strict input validation — the application never holds elevated database credentials in production.

Transport security

All connections use HTTPS with HSTS preloading. The Strict-Transport-Security header ensures browsers never downgrade to HTTP. X-Frame-Options DENY prevents clickjacking. Referrer-Policy restricts information leakage on outbound links.

Browser permissions

The Permissions-Policy header disables access to geolocation, camera, microphone, payment APIs, and advertising tracking APIs (FLoC/Topics). These features are not needed and are explicitly blocked.

Authentication

Sessions use short-lived JWTs with secure cookies. You authenticate with email and password; credentials are verified by Supabase Auth.

See also Privacy.

Last updated April 2026