Engine & deployment

Security notes

What the platform protects, what it does not, and a checklist for operators.

Warning: No external security audit or penetration test has been done. This page describes what the code does and what its own tests check. It is a starting point for a review, not the result of one.

What is protected

AreaHow
AuthenticationKeys and session tokens are random and stored as SHA-256 hashes. Sessions expire after 7 days. Reset, verification and invitation links are signed and single-use.
PasswordsHashed with scrypt. A minimum length, not the email address, not a very common password.
Second factorOptional time-based codes, with recovery codes and a lock-out after wrong attempts.
AuthorisationOne role table, enforced on every authenticated request. A test calls every route with every role.
TenancyEvery lookup checks the workspace. Another workspace's id answers 404.
Third-party credentialsEncrypted at rest: provider keys, sub-account keys, SIP trunk passwords, custom-model keys, webhook headers, two-factor secrets, function-tool tokens and headers. Key rotation is supported.
Outbound requestsWebhook, tool and knowledge-base URLs may not resolve to private addresses.
Provider callbacksPayment and messaging webhooks are checked by signature and amount, and are idempotent. The inbound-call webhook needs the telephony provider's signature when telephony is live. Engine callbacks need the call's own token or the shared secret.
UploadsSize limits per route, type judged by content, files stored under generated names.
Headersnosniff, frame denial, no referrer, HSTS over TLS, no-store on authenticated answers.
Browser accessCORS only for configured origins. Sessions are Bearer tokens, not cookies, so there is no cross-site request forgery surface.
LogsNo secrets, tokens, full phone numbers or transcripts.
BillingAn append-only ledger enforced by the database, and idempotent posting.

What is not protected, or only partly

  • Customer data (transcripts, recordings, contact lists, leads) is not encrypted in the database. Use disk encryption.
  • Recording URLs are signed but do not expire.
  • While a call is live, its session, including tool tokens, is held in Redis in plain text.
  • Request limits are per workspace per minute. There is no per-address limit on authenticated routes and no web application firewall.
  • No single sign-on, no IP allow-lists for API keys, no device approval.
  • Time-based codes are the only second factor.
  • Redaction of personal data in transcripts is pattern-based and will miss things.
  • Webhook deliveries to your endpoint are not signed. Authenticate them with a secret header.
  • The payment and messaging adapters have never talked to the real providers.

Out of scope today

A compromised host or operator, denial of service beyond the rate limits, misuse of calling by a legitimate customer, and the security of the model servers.

Operator checklist

  1. APP_ENV=production, a random SECRET_KEY of 48 or more characters, real database and Redis passwords.
  2. ALLOW_PRIVATE_URLS=false, and REQUIRE_VERIFIED_EMAIL=true.
  3. TLS in front of everything. Trust forwarded addresses only behind your own proxy.
  4. CORS_ORIGINS and SITE_ORIGINS list exactly your dashboard and website.
  5. Operator and metrics tokens set, and /admin and /metrics unreachable from outside.
  6. The engine's shared secret set on both sides; Exotel credentials and allow-lists set on the engine.
  7. Real payment, SMS and email providers configured and tried in test mode.
  8. Stored secrets re-encrypted once with the rotation script after upgrading from an earlier version.
  9. Backups scheduled, copied off the machine, and one restore rehearsed.
  10. Disk encryption on the database, storage and backup volumes. Recording retention decided.
  11. Alerts on the metrics, and logs shipped somewhere searchable.
  12. An external review, and legal review of the compliance features.

Reporting a problem

Report a suspected vulnerability privately through the contact address on this site. Please do not test against other customers' data.