Security

How we handle your users' data.

Plain summaries of the cryptography, retention, and disclosure policy. The legally binding version is the privacy policy and DPA.

Cryptography

Password hashing
Argon2id (libsodium-backed) with memory_cost=65536, time_cost=3. Wall-clock ~50 ms per hash on production hardware.
Symmetric encryption
XSalsa20-Poly1305 via libsodium's crypto_secretbox. Used for challenge expected-answer storage. Per-deployment 256-bit key (APP_KEY) — rotated annually.
HMAC
HMAC-SHA-256 with a separate APP_HMAC_KEY. Used for signing pool image URLs and webhook payloads.
Token format
Verify tokens are 40-byte cryptographically random, base64url-encoded, stored as SHA-256 hashes only. Single-use, 180-second expiry. Plaintext is never written to disk.
Random source
PHP's random_bytes() (libsodium/openssl backend depending on platform). No userspace PRNGs.
TLS
TLS 1.3 minimum, HSTS preload (max-age=63072000; includeSubDomains; preload), HTTP/2.

Data handling

IP addresses
Truncated to /24 (IPv4) or /64 (IPv6) before storage. We never store full IPs. This means we can identify abusive subnets but not individual users behind a corporate or carrier-grade NAT.
User-Agent strings
SHA-256 hashed with a per-deployment pepper. Used for risk scoring, never displayed back, never exported.
Cookies (widget)
None. The widget operates entirely without cookies on the customer's site or in the iframe. No session, no fingerprint cookie, no tracking pixel.
Cookies (dashboard)
One HTTP-only, Secure, SameSite=Lax session cookie. No third-party analytics. Deleted on logout.
Email addresses
Stored hashed (SHA-256 with pepper) in the verification logs; plaintext only in users and email_log tables, with retention limits enforced by cron.
Logs in S3 / object storage
None. Verification logs stay in MySQL with TTL-based purge.

Retention

Challenges
7 days, then purged by daily cron. Includes encrypted expected-answer, mode, truncated IP, UA hash.
Verifications (Free)
30 days, then purged.
Verifications (Pro)
90 days, then purged.
Login history
13 months (used for new-device alert deduplication).
Audit log
13 months. Includes admin grants, key rotations, deletions, billing events.
Email log
90 days. Used for support and deliverability investigation.
Data exports (GDPR Art. 20)
ZIP file kept for 24 hours after generation, then deleted along with its database row.
Deleted accounts
Soft-deleted with a 30-day grace period (user can recover); after that, hard-deleted with a SHA-256 tombstone retained for audit (no PII).

Disclosure & access

Lawful access requests
We respond to legally valid requests from EU Member State authorities according to Schrems-II-aligned procedures. We do not respond to US discovery requests because we don't have a US legal entity or US infrastructure. Records of all requests received are published annually as part of a transparency report.
Subpoenas
We don't have data US courts can subpoena, but if served via mutual legal assistance treaties we'll publish the fact (without case details where lawful).
Operator access
Two named operators have shell access to production. All access is logged. No third-party SRE/support firm has access.
Customer data access
Operators can see your account metadata (email, name, plan, last-login timestamp) for support purposes. We cannot see your users' identities — we don't have them.

Responsible disclosure

Where to report
security@trustedcaptcha.com. We acknowledge within 24 hours and aim for a fix within 14 days for high-severity issues.
Scope
Anything affecting trustedcaptcha.com, challenges.trustedcaptcha.com, cdn.trustedcaptcha.com, and the verify API. The widget loader and iframe are in scope. Customer-controlled subdomains (e.g. their CNAMEs pointing at our service) are not in our scope; report to the customer.
Out of scope
Volumetric DDoS, social engineering of our team, theoretical risks not yet exploited (e.g. cipher downgrades that don't apply to TLS 1.3+).
Recognition
Hall of fame on this page for confirmed findings. We don't currently offer cash bounties.