Security
Last updated: August 2026
How Mizan protects your data: encryption, access control, and a design that minimizes what we hold in the first place.
Overview
Mizan's security posture rests on three pillars: strong encryption for the credentials we hold, strict per-owner access control on every record, and a data model designed to avoid collecting sensitive content in the first place. We run on managed infrastructure (Vercel, Railway, Neon, Redis) so that patching and hardening are handled by the providers whose business it is.
Encryption
| Transport | All traffic between your browser, our API, and provider endpoints is encrypted with TLS 1.2+. |
| Provider credentials | API keys you connect are encrypted at rest with AES-256-GCM using a per-value random IV and authenticated tag. They are never logged and never returned to the dashboard after setup. |
| Gateway keys | Mizan-issued keys (mizan_rt_...) are stored only as one-way hashes. We cannot read them back; you see them once at creation. Only the key prefix is stored in plaintext for display. |
| Payments | Card details are processed by Stripe and never transit our servers. We store only transaction metadata and a reference to the Stripe payment intent. |
| Owner scoping | Every record is scoped to an owner (org or user). Queries are constrained by the authenticated owner at every layer; there is no cross-tenant path. |
| Webhooks | Clerk and Stripe webhooks are signature-verified before processing. Internal cron routes are protected by a secret bearer token. |
Key management
The AES-256-GCM encryption key used for provider credentials lives in the backend environment variables, separate from the database, and is never written to disk alongside the data it protects. Each credential is encrypted with its own random 96-bit IV and authenticated with a GCM tag, so tampering is detected. Router keys are one-way hashed, and usage limits are enforced with atomic counter updates rather than read-modify-write races.
Access control
Every request to the backend authenticates with a short-lived Clerk JWT. The owner (your personal workspace or your organization) is resolved from the token, and every database query is scoped to that owner — a user can only ever read or mutate their own records. In organizations, members see only usage attributable to the keys they created unless an admin grants wider visibility. Cron and webhook endpoints bypass JWT only where the request is authenticated cryptographically (signature or bearer secret).
Privacy by design
The strongest security control is not storing the data. Gateway requests are forwarded to the provider and returned to you without ever being persisted; we keep only per-request metadata. Error messages are truncated to a bounded length before logging. Email scanning is opt-in per connection, and scanned receipt content is truncated at ingestion. See our Data Retention policy for the full picture.
Infrastructure
The frontend runs on Vercel; the backend, background workers, and cron run on Railway; the database is Neon Postgres; Redis handles caching and queues. All of these providers maintain their own security and compliance programs (see our Subprocessors page). Where provider credentials must be sent to a third party (for example, your own connected provider when you route traffic through it), that transmission is TLS-encrypted end to end.
Responsible disclosure
Found a vulnerability? Please report it privately to naim@app-mizan.com rather than filing a public issue. We'll acknowledge reports promptly, keep you informed of our progress, and credit you unless you prefer to stay anonymous. We do not currently operate a paid bug bounty program.