Security
Updated
This page lists the controls that are in place today, with the mechanism behind each one. It does not list certifications, because there are none yet, and it does not claim HIPAA, because the service is not one.
Controls
| Control | How it works |
|---|---|
| Signed webhooks | Every delivery carries webhook-id, webhook-timestamp and webhook-signature, an HMAC-SHA256 over id.timestamp.body. The receiver rejects a timestamp older than 300 seconds. A rotated secret keeps signing for 24 hours. |
| Idempotency | Every mutating call accepts an Idempotency-Key. A repeat returns the same resource with Idempotent-Replayed: true. A different body under the same key is refused. Provider and payment events are deduplicated by a row written in the same transaction as their effect. |
| Private documents | No document has a public URL. The only way to fetch bytes is a signed URL minted for the owner, valid ten minutes. Documents are deleted after 30 days by default, inbox items after 90, and the owner can delete earlier. |
| Approval binding | An approval covers one document hash, one destination, one sender, one amount and an expiry. A change to any of them invalidates it. A delegated policy is evaluated on the server from the quote and the document row, never from prompt text. |
| Untrusted inbound content | Text from a received fax is listed under untrusted on every MCP result and rendered as plain text. The policy engine and every tool decision never read it. Ids passed as tool arguments are format-checked before any request leaves the tool. |
| Agent keys cannot widen themselves | An agent key is never issued the scopes that decide approvals, write policies, mint keys, change budgets or manage webhooks. Routes that do those things refuse any key with an agent id. Disabling an agent revokes its keys in the same transaction. |
| Tenant isolation | Every table and every query carries the organization id. A foreign id answers 404. A sweep in CI walks every id route with a second organization and fails the build when a route has no fixture. |
| Audit trail | Every mutation writes an append-only audit row in the same transaction. The actor is a user, an API key prefix, an agent or a system job. Never a document body. The ledger and the audit table refuse updates and deletes at the database. |
| Access-gated admin | The admin host sits behind Cloudflare Access. The API verifies the Access assertion on every admin call, RS256 against the team's keys, and checks the email against an allow list. Headless access uses a service token with its own identity in the audit log. |
| Secrets | Production configuration lives on the host as environment, never in the repository or CI. API keys are stored as a peppered HMAC and shown once. Webhook secrets are encrypted at rest. Logs run through a redaction processor that is unit-tested. |
| Mail authentication | SPF with -all, DKIM for both senders, DMARC, MTA-STS, TLS-RPT, DNSSEC and CAA on faxforagents.com. Mail from us carries no image and no document. |
| Processing region | Nuremberg, Germany (EU). Backups are encrypted and stored in the EU. No residency promise is made beyond that statement. |
What delivered means
A job is written as delivered only when the provider's report is stored on the attempt. The receipt names the provider reference, the document hash, the pages and the time. A job without a report stays active or ends unknown, and an unknown job is never retransmitted on its own. The receipt is a record, not legal proof that a person read the document.
Subprocessors
| Who | What for | What they see |
|---|---|---|
| Hetzner Online GmbH | hosting, Nuremberg, Germany | every service, the database and document storage |
| Cloudflare, Inc. | DNS, tunnel, edge, Access for the admin host | every request to a faxforagents.com host |
| Telnyx LLC | fax transmission and numbers | the documents sent and received, destination and sender numbers |
| Stripe, Inc. | card payments, invoices, the customer portal | billing email, card details on Stripe only, never on our servers |
| Resend | transactional mail | the recipient address and the mail body, which never carries a document |
| Google Workspace | the hello@ mailbox | mail you send to us |
| Backblaze, Inc. | encrypted backups | database dumps, in the EU region |
Not in place
No SOC 2 report, no ISO 27001 certificate, no HIPAA business associate agreement, no penetration test report yet. OAuth 2.1 for the MCP server is planned and not live, so an API key is the only credential. When any of these changes, this page changes with it and the changelog records the date.
Reporting a problem
Write to hello@faxforagents.com. The same address is in security.txt. We answer within two working days and we do not run a bounty.