Skip to main content

Every claim, in one checklist.

Architecture deep-dive lives at /security; this page is what you skim before scheduling a vendor review call. Each claim says how it works, and some link to a public doc. For anything else, email [email protected].

Authentication & access

  • ✓

    API keys are scrypt-hashed at rest

    The readable key is never written to any storage, anywhere — it's one-way scrambled (scrypt) first. The scrambler's strength settings (hash params N=2^15, r=8, p=1) live alongside the hash so keys can be verified without ever storing the key itself. A database breach surfaces hashes, not credentials.

  • ✓

    MFA: TOTP + recovery codes

    Two-factor login uses authenticator-app codes (TOTP). The seed that generates your codes is stored encrypted (AES-256-GCM at-rest encryption of TOTP secrets). Recovery codes are scrypt-hashed — one-way scrambled, mirroring API key handling. Dangerous admin actions demand a fresh MFA check even if you're already signed in (a "step-up" check before risky admin actions). That check stays fresh for 15 minutes.

  • ✓

    OAuth 2.0 (invite-only) with PKCE-S256

    Third-party app access (OAuth) requires admin invitation (no self-service client registration). Every connection uses PKCE-S256 — an extra proof that the app finishing a login is the same one that started it. App secrets (client_secret) are sha256-hashed at rest; login codes work exactly once (one-shot authorization codes); and access tokens are opaque random strings (no JWT), so a stolen token carries no readable data.

  • ✓

    Device-code sign-in for the desktop app

    The desktop app shows a short code; you approve it in the dashboard while signed in, and the app receives a restricted credential of its own — nothing is copied by hand. The code is stored only as a sha256 hash, compared in constant time, expires after five minutes, and works exactly once.

  • ✓

    Active sign-ins: listed, revocable, and ended by a password change

    The dashboard lists every active sign-in on your account and lets you revoke one, or all except the one you are using. Sign-in tokens are stored only as sha256 hashes and expire; changing your password ends every other sign-in at once.

  • ✓

    Your own AI key, desktop-app control keys and live-video credentials: encrypted at rest (AES-256-GCM)

    Three kinds of secrets that would be as damaging as passwords if leaked are stored encrypted (AES-256-GCM) under the same server-held key as two-factor login secrets: (1) your own AI key, if you bring one for the AI agent; (2) the per-session keys that authenticate desktop-app control commands; and (3) the live-video credentials we use to issue the short-lived access tokens the desktop app needs to watch a session. All three are decrypted in memory only when needed and never logged; your AI key and the live-video credentials are never returned in responses. Our logging and error-reporting also scrub secrets automatically in case one ever ends up inside a message.

Transport & proxies

  • ✓

    Every connection is encrypted (TLS 1.2 or newer)

    Every connection to our servers (api.driftstack.dev and app.driftstack.io) is encrypted with TLS 1.2 or newer, through Cloudflare, our edge network. No unencrypted (plain HTTP) page exists on any path, and every release is checked for this automatically before it ships.

  • ✓

    Your own proxy or VPN, per profile

    Each profile can use its own exit to the internet: a SOCKS5 proxy, an OpenVPN file (.ovpn), or a WireGuard file (.conf) — VPN exits are on paid plans. Driftstack checks the configuration before launch — a SOCKS5 proxy with a real connection through it to our own address-echo endpoint, so your exit address is never sent to a third-party checker; an OpenVPN file for directives that would run a program, which are refused with the offending line named; a WireGuard file by reading only its keys, addresses, endpoint, allowed IPs, DNS and MTU, so its PostUp/PreUp hooks are never used — and asks your proxy to handle DNS lookups so they are not sent around it. A VPN tunnel carries everything the profile does, including WebRTC and HTTP/3. Whether UDP, WebRTC and QUIC traffic travels through a SOCKS5 proxy depends on what your proxy supports: the proxy's Test reports whether it answers, its latency, the country and city it exits from, whether it can carry WebRTC, what to expect for HTTP/3 (an estimate until it has been measured) and — where it can be measured — which operating system the exit appears to run, and a running session shows whether HTTP/3 is actually in use. On a proxy that cannot carry HTTP/3, it is switched off rather than leaked. Proxy passwords and VPN keys are stored encrypted (AES-256-GCM). The desktop app launches a profile only through the proxy or VPN you chose for it, never one it picks for you; every agent session names one of your saved proxies by its proxy_id. Driftstack does not route your traffic through a shared exit of its own. Driftstack does not store copies of the pages your sessions load; an AI session's transcript can quote page text.

Webhooks & integrations

  • ✓

    Outbound webhooks are HMAC-SHA256 signed

    A webhook is a message we send to your systems when something happens. Every delivery carries X-Driftstack-Signature — a cryptographic signature (HMAC) over the timestamp + message body. Your code verifies it via one SDK helper; messages older than the allowed timestamp tolerance window are rejected, so an intercepted copy can't be re-sent later (replay attacks).

  • ✓

    Payment notifications (Stripe, Confirmo) are signature-verified before anything changes on your account

    Payment notifications must prove they're genuine before we change anything on your account. Stripe: timestamp + HMAC-SHA256. Confirmo: SHA-256 over the message and a shared secret, and we then read the payment's state from Confirmo itself. Each signature check runs over the exact bytes we received, so a message altered in transit is rejected.

Data residency & retention

  • ✓

    Account data in the EU; sessions on Macs in the US or the Netherlands

    Servers in Falkenstein, Germany (Hetzner); database in Frankfurt (Neon); file storage on Cloudflare R2, which keeps copies in both the EU and the US. iPhone Safari sessions run on US infrastructure (MacStadium) under the EU's Standard Contractual Clauses (SCCs) and the EU-US Data Privacy Framework, or in the Netherlands (Green Mini host) — see data residency. Full sub-processor list at /trust/sub-processors.

  • ✓

    Direct captures and local recordings

    Screenshots and other captures you request through the sessions API are returned to you directly in the response, and the capture service keeps no copy — you decide where to store them. In an AI-agent session the screenshot from each step is kept in server memory so the desktop app can show it: at most 20 per session, served only while the session is running and for no more than 30 minutes after it was taken, then dropped. It is never written to disk. Desktop recordings are saved only on your own computer; the recording feature never uploads them. See /docs/recordings for exactly what is and isn't stored.

  • ✓

    Audit log: exportable as CSV or JSON

    Account-security and management events — key creation, rotation and revocation, two-factor enrollment, profile changes, webhook secret rotations, sign-ins and password changes — are recorded with who acted and on whose account. Read the log in the dashboard, or export it as CSV or JSON (up to 10,000 rows per export; your GDPR Article 20 portability right).

  • ✓

    Account deletion

    Profile data and saved secrets are erased within 30 days of closing the account; billing records are kept 7 years (Dutch tax law). Copies in our encrypted backups are gone within a further 40 days. Per our Privacy Policy and DPA.

Monitoring & incident response

  • ✓

    Public incident history + status page

    Customer-impacting outages are posted publicly; for outages and major incidents, root cause and remediation follow within seven business days of the incident closing. Live status at status.driftstack.io, with email subscriptions for incident updates; historical archive at /trust/incidents.

  • ✓

    Vulnerability reports: acknowledged in one business day, triaged within 7 days

    We won't take legal action against good-faith research ("safe-harbour"). Reporters agree to keep a finding private for 90 days while we fix it (the coordinated disclosure window), extendable on agreement. Full policy at /trust/compliance.

  • ✓

    Scripted failure drills (chaos engineering)

    An email-vendor outage, the cache going down, webhook-signature failures — each has a scripted drill. Nothing runs them on a schedule. Drills run as simulations by default; actually breaking things requires a deliberate, explicit decision by our team.

Still need a deeper look?

The architecture deep-dive at /security explains all six security promises in detail. For current compliance status and vulnerability reporting, see /trust/compliance. Anything else, just email.

Email security