Security

What we do to protect the credentials you trust us with and the data we fetch on your behalf.

Credentials at rest

Every external-service credential you give Veriti (TONO password, DistroKid password) is encrypted with AES-256-GCM before it touches the database. Each row uses a random initialization vector and authentication tag. The encryption key is 32 bytes generated by openssl rand -hex 32 and stored outside the database in our secrets manager.

Decryption only happens server-side at the moment a sync is run. Plaintext credentials never appear in logs, never get serialized into API responses, and never reach the browser.

Sessions & auth

Veriti uses Supabase Auth (Postgres + JWT). Sessions are validated server-side on every API call with auth.getUser() — we never trust client-side cookie state alone. Admin-only routes are checked at three layers: middleware, page/layout, and the underlying API route.

Database isolation

Every table in the Veriti database has row-level security enabled. Users can only read or write rows they own (enforced via Postgres policies tied to auth.uid()). Service-role access (used for writes on RLS-protected tables) is restricted to server-side code and never reachable from a browser bundle.

Anonymous tokens

The few endpoints that issue tokens to unauthenticated users (the /find scan report flow) sign them with HMAC-SHA256, include a short-lived expiry, and verify with constant-time comparison to prevent timing attacks.

Input validation

Every API route validates its input — type, length cap, and where applicable format regex (IPI = 9-13 digits, Spotify ID = 32-char alphanumeric, ISWC = T-NNN.NNN.NNN-N). Validation happens before any external API call or database write.

HTTP security headers

The marketing site and the portal set X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, a restrictive Permissions-Policy, and HSTS (1 year, includeSubdomains, preload) in production.

Vulnerability disclosure

Found something? Email security@veriti.so rather than opening a public issue. We acknowledge within 24 hours and work with you on coordinated disclosure timing.

Veriti is in active development; controls are added incrementally as we approach public launch. The internal security audit and progress tracker are maintained in the repo and reviewed each release.