Skip to main content

Privacy

Security

How credentials you hand us are stored, who can reach them, and what we never keep.

This page is specific on purpose. "Industry-standard encryption" tells you nothing; the algorithm, the key length and where the key lives tell you whether to trust us. Every figure below is read from the code by a test, so the page cannot quietly drift from what runs.

Credentials you connect

Three kinds of secret can be handed to us, all optional:

SecretGiven whenUsed for
Google refresh tokenYou connect Search Console or Google AnalyticsFetching your search terms or importing GA4 history on your behalf
Payment provider API keyYou connect Stripe, Lemon Squeezy, Paddle or PolarReading payments to attribute revenue to visits
Payment webhook secretSame connectionVerifying that incoming payment events really came from the provider

How they are stored

AES-256-GCM, at rest, with a per-record random nonce.

  • The cipher is AES in Galois/Counter Mode with a 256-bit key. GCM is authenticated: a stored value that has been altered — by a fault or by hand — fails its authentication tag and is refused rather than decrypted into garbage.

  • Every encryption draws a fresh 96-bit nonce from the operating system's random source. Two identical tokens stored twice produce two unrelated ciphertexts.

  • The stored value carries a version prefix, the nonce, the authentication tag and the ciphertext, hex-encoded. The database enforces that shape with a check constraint, so a plaintext credential cannot be written to the column at all — a bug that tried would be rejected by the database, not discovered later.

Where the key lives

Outside the database. The 256-bit key is an environment variable on the application server and is never written to the database, to logs, or to any file in the repository. Reading a database backup, or the database itself, yields ciphertext that cannot be opened without the server's key.

Google tokens and payment-provider secrets use two separate keys, so a compromise of one does not open the other.

When they are decrypted

Only in server memory, only for the duration of one API call — refreshing a Google access token, fetching a report, verifying a webhook signature. The decrypted value is passed to the outbound request and discarded. It is never logged, never returned to the browser, and never cached.

Revocation

Disconnecting an integration revokes our access at the provider and deletes the stored credential. If you revoke access on Google's side first — from your Google account's list of connected apps — Google sends us a signed security event and we delete the credential at once; we subscribe to Google's Cross-Account Protection for exactly this. Should that notice not arrive, our next attempt to use the credential fails and we delete it within the hour. See the privacy policy for what stays (fetched data) and what goes (the credential).

Credentials we never hold

  • Your password. Sign-in is handled by our authentication provider; we see a session, never a password. Signing in with Google leaves us no lasting Google token at all.

  • Card numbers. Checkout runs on Stripe's pages; we store an identifier that points at your Stripe customer record and nothing from the card.

  • Visitor identities. The tracking script sends no name, email or cross-site identifier, and the collector never stores an IP address — only a salted hash that rotates daily. See what the script sends.

Access to your data

  • Every table is protected by row-level security: a query from your session can return only rows belonging to organisations you are a member of, and the database enforces this — not application code.

  • Site-level scoping restricts a team member to the sites you choose, again enforced by the database.

  • API keys are stored as SHA-256 hashes; the key itself is shown once at creation and cannot be recovered from our records.

  • Staff do not read customer data except to investigate a fault you have reported, and then only the data needed for that fault.

Reporting a vulnerability

Write to security@truestat.io. We answer within two working days and do not pursue researchers acting in good faith.

Was this page helpful?

Last updated September 8, 2026