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
| Area | How |
|---|---|
| Authentication | Keys 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. |
| Passwords | Hashed with scrypt. A minimum length, not the email address, not a very common password. |
| Second factor | Optional time-based codes, with recovery codes and a lock-out after wrong attempts. |
| Authorisation | One role table, enforced on every authenticated request. A test calls every route with every role. |
| Tenancy | Every lookup checks the workspace. Another workspace's id answers 404. |
| Third-party credentials | Encrypted 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 requests | Webhook, tool and knowledge-base URLs may not resolve to private addresses. |
| Provider callbacks | Payment 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. |
| Uploads | Size limits per route, type judged by content, files stored under generated names. |
| Headers | nosniff, frame denial, no referrer, HSTS over TLS, no-store on authenticated answers. |
| Browser access | CORS only for configured origins. Sessions are Bearer tokens, not cookies, so there is no cross-site request forgery surface. |
| Logs | No secrets, tokens, full phone numbers or transcripts. |
| Billing | An 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
APP_ENV=production, a randomSECRET_KEYof 48 or more characters, real database and Redis passwords.ALLOW_PRIVATE_URLS=false, andREQUIRE_VERIFIED_EMAIL=true.- TLS in front of everything. Trust forwarded addresses only behind your own proxy.
CORS_ORIGINSandSITE_ORIGINSlist exactly your dashboard and website.- Operator and metrics tokens set, and
/adminand/metricsunreachable from outside. - The engine's shared secret set on both sides; Exotel credentials and allow-lists set on the engine.
- Real payment, SMS and email providers configured and tried in test mode.
- Stored secrets re-encrypted once with the rotation script after upgrading from an earlier version.
- Backups scheduled, copied off the machine, and one restore rehearsed.
- Disk encryption on the database, storage and backup volumes. Recording retention decided.
- Alerts on the metrics, and logs shipped somewhere searchable.
- 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.