Security
Last updated: 2026-06-11
TwinFlow reads workflow metadata from tools that matter to your business, so we hold ourselves to a simple standard: collect the minimum, encrypt what we keep, and be specific about both. TwinFlow is built and operated by a senior security engineer. This page describes our actual measures — no badges, no vague claims.
The data we don't have
The strongest protection is not holding the data at all. TwinFlow's connectors request only workflow metadata — statuses, assignees, timestamps, priorities, labels — and never request ticket descriptions, comments, email bodies, attachments, or repository code. What we store is narrower still: event logs of who did what and when, not the content of the work. The per-tool breakdown is in our Privacy Policy.
OAuth scope minimalism
Access scopes per connector, exactly as requested:
| Gmail | gmail.readonly — and we request messages in metadata format, so full email bodies are never returned to us, even though the scope would technically allow reading them. |
| Linear | read — read-only OAuth scope. |
| Jira | read:jira-work, read:jira-user, write:jira-work, offline_access — the write scope exists for exactly one feature: the optional, user-triggered “create ticket” button (scans never write); offline_access lets us refresh the token so you don't have to re-authorize. |
| Salesforce | OAuth; scans query Case and CaseHistory metadata via read-only SOQL queries. |
| Zendesk | API token you provide; scans only call read endpoints. |
| GitHub | Personal access token you provide; scans only call read endpoints on the Issues API. Repository code is never accessed. |
Scans never modify your tools. The only write operation in the entire product is the "create ticket" button, which runs only when you click it and creates only the ticket you asked for.
Credential handling
- OAuth tokens and API credentials are encrypted at rest with AES-256-GCM, using a fresh random nonce per value. The encryption key lives only in the server environment — never in the codebase or the database.
- Tokens are never written to logs. Our logging layer redacts sensitive query parameters (auth codes, tokens, session IDs) and scrubs SQL statements and parameters out of error messages before anything is recorded.
- Card data never touches our servers — payment details go directly to Stripe.
- You can revoke our access at any time: disconnect in TwinFlow, revoke the OAuth grant in your tool, or rotate the API token you gave us.
Infrastructure
- Hosting on Hetzner in the European Union (Helsinki, Finland data center).
- All traffic between your browser and TwinFlow is encrypted with TLS.
- PostgreSQL and Redis are not exposed to the internet — they are bound to localhost and reachable only inside the server's private container network, and Redis additionally requires password authentication.
- The application sits behind an Nginx reverse proxy with security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy).
- Server hardening: SSH is key-only (password authentication disabled), a default-deny firewall, fail2ban, and automatic security updates.
- Application containers run as non-root users.
- Every database row is scoped to your tenant ID, and every API request is authenticated via Clerk-issued JWTs before it can touch tenant data.
Backups
- The database is backed up nightly.
- Every backup passes integrity gates (size floor plus a restore-catalog parse) before it counts — a truncated backup fails loudly rather than sitting silently broken.
- Local backups are retained for 14 days, then automatically deleted.
- An off-site copy goes to Backblaze B2 using an append-only flow: the server's replication path can add backups but can never delete or overwrite the off-site history, so even a fully compromised server cannot destroy it.
- Restores are drill-tested against a scratch database, not assumed to work.
AI data handling
AI features are powered by Anthropic's Claude models. We send aggregated scan output — counts, rates, cycle times, step names, bottleneck statistics — plus text you type into the chat features. Ticket bodies and email contents are never sent, because we never collect them. Under Anthropic's commercial API terms, API data is not used to train their models.
Supply chain
Dependency security scanning runs in CI on every push: Node dependencies are audited with the build blocking on high or critical vulnerabilities, Python dependencies are audited with pip-audit, and builds install from committed lockfiles only.
Compliance roadmap
We are a small team and we won't claim certifications we don't have. SOC 2 Type II is on our roadmap. In the meantime, this page and the Privacy Policy are written to be specific enough that your security team can evaluate us on facts.
Responsible disclosure
If you find a vulnerability, email support@flowmri.io with enough detail to reproduce it. We will acknowledge your report, keep you updated, and credit you if you'd like. Please give us reasonable time to fix the issue before any public disclosure, and don't access other customers' data while testing. We don't run a paid bounty program yet.