Security Posture
This is a plain-language description of how Eformogi runs in production. If something here stops being true, this page changes. If we can't honestly say something, we don't say it.
Last updated: September 8, 2026
Where your data lives
Your record, consent receipts, and audit log live in a managed Postgres instance on Supabase (AWS us-east-1). Row-Level Security is enabled on every table that holds user data. Every read and write goes through a policy that checks the authenticated user ID against the row's owner.
On endpoints that touch only a user's own data, the API queries the database using a client bound to that user's session, so RLS is enforced at the database, not just in application code. Manual ownership filters remain as a second layer.
Our API runs as stateless serverless functions on Vercel. The functions hold no durable state. Logs are retained by Vercel for 30 days and are not exported to any third party.
What is published
The protocol this record is written in is public, so a reviewer does not have to take our description of it on faith. The chapters (receipt grammar, witness attestation, key model, transparency log, verification, export) are at /spec. The reference verifier, which checks a record without contacting our servers, is at /spec/verifier. The license the protocol ships under is at /spec/licensing. What has and has not been independently verified is stated in the Trust Report at /spec/trust-report, which is the document to read before you believe anything on this page.
Encryption
In transit: TLS 1.2 or higher on every public endpoint. HSTS is set. We do not accept plaintext connections.
At rest: AES-256 on the database (Supabase-managed) and on object storage. Backups are encrypted with the same key class.
Subprocessors
We use a small number of infrastructure vendors. We try not to add new ones. The current list:
- Supabase (database, auth, storage)
- Vercel (API hosting, edge, static assets)
- Upstash (rate-limit counters, no user content)
- Stripe (payments: receiver verification plans, issuer subscriptions billed per learner, and optional Family Pro subscriptions for families)
- Resend (transactional email delivery)
- Google Gemini and OpenAI (AI extraction, only on user request, only with redaction where applicable)
- Sentry (crash reports, with PII scrubbed at the SDK)
AI vendors do not receive your full record. They see the single document the user submitted, and we don't train models on that data. If this changes, this page changes first.
Authentication
Users sign in with an email sign-in link or a 6-digit email code through Supabase Auth. Sessions are JWTs scoped to the user. We never see or store passwords.
Organizations (counselor practices, schools, microschools) have their own auth surface and are isolated by org_id on every row they touch.
Rate limiting and abuse
Public endpoints are rate-limited per IP using a durable counter in Upstash Redis, so limits survive across serverless cold starts. Authenticated endpoints are additionally limited per user. If Redis is unavailable, the in-memory per-instance limiter still applies.
Consent and audit
Every time a consent is granted, used, or revoked, we write a signed receipt to the audit log. The log is append-only from the user's perspective. The user can download their full audit log at any time from Settings.
Audit records are retained for seven years. We believe that's the right minimum for anything consent-related.
Data export and deletion
You can export your full record as JSON or PDF from Settings, without contacting us. Deletion is also self-serve.
When you delete your account, we hard-delete your record, documents, share links, AI usage records, and the routine audit events (sign-ins, page views, session activity).
Consent receipts and verifiable credentials are pseudonymized rather than deleted: we strip your user ID and replace it with a one-way hash. The artifact survives so we can answer "did this institution ever have permission to receive this data?" years later, but the row no longer points back to a person. This is the integrity guarantee a consent layer needs to be useful at all.
Breach response
If we discover a breach that affects your data, we will notify affected users within 72 hours of confirmation. That SLA is in our Terms and in our institutional contracts. If local law requires a faster notification, the faster one wins.
What we don't do
- We don't sell data. Not to advertisers, not to brokers, not to anyone.
- We don't train AI on your record.
- We don't use tracking pixels in email.
- We don't run third-party analytics on authenticated pages.
- We don't keep data after you delete your account beyond what the audit log and legal retention require.
What we're still working on
Honesty requires saying what isn't done yet.
- SOC 2 Type II for Eformogi: planned, not yet commissioned. Our providers publish their own reports; we hold none.
- End-to-end client-side encryption for every family: on the roadmap. It ships today as the opt-in Own Your Keys ceremony, and the tradeoff is search and AI assistance.
- Bug bounty: informal today (email security@eformogi.com), formal program coming.
Responsible disclosure
Found something? Email security@eformogi.com. We'll acknowledge within one business day. We won't pursue legal action against good-faith researchers.