Security

LAST UPDATED · September 2026

Credential fields

Sensitive answers (hosting logins, ad accounts) are encrypted at rest with AES-256-GCM under a versioned key. They are masked in the dashboard by default; revealing one writes an audit row before the decrypt happens, so attempts are recorded even when decryption fails.

Client links

Client portals use 128-bit random tokens wrapped in an HMAC-signed, expiring envelope. Links can be re-issued (rotating nothing) and expire on a fixed TTL; the raw token never appears in emails or logs.

Multi-tenancy

Every tenant table carries an account id and is protected by Postgres row-level security — not just application filtering. Public API and MCP access is scoped to the key's account and its read/write scopes; keys are stored as SHA-256 hashes and can be revoked instantly.

Webhooks

Outbound webhook payloads are signed with a per-endpoint HMAC-SHA256 secret (X-IntakeFlow-Signature). Verify the signature against the raw body before trusting a delivery. Delivery attempts and outcomes are logged for audit.

File storage

Uploads go to a private bucket (or your own connected S3/Dropbox/Drive) with per-account byte quotas, type allow-lists, and a 25 MB per-file cap. Files are served only through authenticated, short-lived links.