Security
Fromenance is a communication provenance platform that asks institutions to route customer mail through it, so the security posture has to be finished before the first pilot rather than after. This page is the public overview; a DPA and answers to a full vendor questionnaire are available from your Fromenance contact.
By the end you will know how tenants are isolated, what is encrypted with which key, why the verdict path is deterministic, who the subprocessors are, and how to report a vulnerability.
Threat model in one paragraph
Section titled “Threat model in one paragraph”The customer facing question is “did my institution send this?”. The attacker’s goals are to make a lure verify, to make a real message fail, to learn who a message was sent to, or to read other institutions’ data. The design answers each: verify codes are recipient bound and checksummed, so a copied footer resolves to Not verified and is flagged as a replay; matching is deterministic, so there is no model to prompt; recipients exist only as keyed hashes; and every tenant owned row carries a tenant id enforced in the data layer.
Tenant isolation
Section titled “Tenant isolation”- Every tenant owned table has
tenant_id, and every query runs through a scoped repository that requires it. Route handlers cannot build cross tenant queries. - Object storage keys are prefixed per tenant. API keys and site keys are bound to one tenant.
- An automated suite asserts no cross tenant read on every endpoint on every change.
- Fromenance operators can see per tenant health, rejected inbound reasons, and cross tenant indicator counts. They cannot see submissions or raw mail through those views.
Encryption and keys
Section titled “Encryption and keys”| Data | Protection |
|---|---|
| Submitter addresses, subjects, source configuration, webhook and source secrets, the recipient hashing secret | AES-256-GCM under a per tenant data key |
| Raw MIME and screenshots | AES-256-GCM under the tenant data key, stored in Cloudflare R2 under a per tenant prefix, deleted at the end of the retention window with an audit record |
| Per tenant data keys | Wrapped by a master key that exists only in the Worker runtime’s secret store, never in code or configuration files |
| API keys | SHA-256 hashed at rest, shown once, scoped, revocable, with last use tracking |
| Recipient addresses | Never stored. Registrations carry hmac-sha256:<hex> computed with a per tenant secret; the raw address is hashed in your process by the SDK and rejected by the API if sent in clear |
| Content | Never stored in normalized form. A 64 bit SimHash and a SHA-256 are one way |
| Transport | TLS everywhere; the API is served only over HTTPS |
Secrets rotate: the master key yearly, database and object storage credentials quarterly. There are no long lived credentials in the repository or in CI configuration.
No model on the verdict path
Section titled “No model on the verdict path”Extraction and matching are regular expressions, MIME parsing, SimHash, and HMAC comparison. Where a vision model is used to read a screenshot, its output is treated as untrusted text that only feeds those same deterministic extractors; it cannot change a verdict. If a language model is added later for lure classification, its output will be a label in a fixed schema that can never change a verdict from Verified. Prompt injection through a forwarded message has no target.
Inbound trust
Section titled “Inbound trust”Mail to a tenant inbox is processed only when it authenticates for a domain the tenant owns: a DKIM signature that verifies for the domain or an ARC chain whose last seal is by it, checked by Fromenance itself on the raw message, and a _fromenance.<domain> TXT record whose token matches the tenant. Anything else is held for 24 hours for diagnosis and never answered. Details in Domains and mail.
Replies never quote the forwarded message, never include its links or its sender, state only whether a registered communication matches, and are sent only to the customer who asked, from the tenant’s reply identity.
Abuse handling
Section titled “Abuse handling”- The verify page is rate limited per IP and per site key, requires an allowed origin, and escalates to Cloudflare Turnstile when a key exceeds its normal rate.
- Anyone can forward anything through a tenant’s rule, including attempts to poison the fraud list. Fraud list entries come only from analyst action or confirmed campaign clustering, never from a single submission.
- Footer replay is reported to the customer as Not verified and flagged internally with high priority.
- Provider webhook signatures are verified on every request with a 5 minute replay window where the provider supplies a timestamp. Outbound webhooks are HMAC-SHA256 signed with a per endpoint secret.
Platform
Section titled “Platform”| Layer | Provider |
|---|---|
| API, inbound processing, queues, cron, edge lookups, object storage, OCR | Cloudflare Workers, Queues, D1, R2, Workers AI |
| System of record | Neon Postgres |
| Email in and out | Resend |
| Billing | Stripe |
| Error monitoring | Sentry |
Admin sign in is by magic link or passkey through Better Auth. Operator access sits behind Cloudflare Access with a hardware key requirement on top of application auth, and every operator action is audited. Deployments run only from CI on the main branch, with dependency scanning.
Subprocessors
Section titled “Subprocessors”Cloudflare (compute, storage, queues, edge network), Neon (Postgres), Resend (email delivery and inbound), Stripe (billing). Sentry receives error events that contain request ids and stack traces, not message content. The DPA lists each with its role and region.
Data residency and retention
Section titled “Data residency and retention”All storage and processing is in the United States. Retention defaults to 90 days and is tenant configurable from 7 to 730 days; submitter addresses are purged 30 days after the reply; rejected inbound is deleted after 24 hours. Full detail on Retention and privacy.
Compliance roadmap
Section titled “Compliance roadmap”SOC 2 Type 1 is targeted within 12 months of the first paying tenant. Until then the controls above, the DPA, and the tenant isolation test suite results are available for review.
Responsible disclosure
Section titled “Responsible disclosure”Report vulnerabilities to security@fromenance.com. Include the request id or URL, steps to reproduce, and the impact you believe it has. You will get an acknowledgement within two business days and a status update when the issue is triaged. Please do not test against tenants you do not own, do not access data that is not yours, and give us reasonable time to fix before disclosing publicly. We do not pursue legal action against good faith research that follows these rules.