Skip to content

Security ​

Allowed origins ​

A bot's public id is in your page's source, so anyone can copy it. Its allowed origins (security.allowedOrigins, in the bot's Security tab) decide which sites may use it:

PatternMatches
https://www.example.comExactly that origin
https://*.example.comAny subdomain over https (not example.com itself)
example.comhttps://example.com and http://example.com
http://localhost:*localhost on any port
*Any site

An empty list allows any site; the admin panel warns about it. The list is enforced three times:

  • the bot's settings are only given to pages on those origins (others get origin_not_allowed);
  • the chat window is sent with a frame-ancestors policy listing them, so the browser refuses to show it framed by any other site;
  • the WebSocket checks the page the chat is on when it connects.

Origins are scheme, host and port: no paths. Publish after changing them.

Keys and secrets ​

  • Provider keys, webhook secrets, identity secrets, tool secrets and MCP headers and environment are encrypted at rest (AES-256-GCM) with the master key, each bound to the row it belongs to. They are never sent to a browser. The master key can be changed: see Backups.
  • API tokens, sessions and visitor tokens are stored as hashes.
  • Passwords are hashed with scrypt; sign-in is limited to 8 attempts per IP and email address every 5 minutes.
  • The admin panel's session cookie is httpOnly and SameSite=Lax, and changes need a CSRF token.
  • Server logs leave out authorization headers, cookies, keys, passwords, tokens and secrets.
  • The audit log (admins: GET /api/v1/audit, newest first, { entries, nextBefore } for paging) records who changed what: bots (created, copied, published, paused or set live, restored, deleted, identity secret replaced), custom faces, provider connections, HTTP tools, MCP servers, secrets, knowledge sources, webhooks, API tokens, team members and invitations, workspace settings, password changes, conversation take-overs, releases and deletions, deleted leads and erased visitors. It records the target, never the request body (which can hold keys).

Visitors and the agent ​

  • Identity: with security.identity.mode: required, only visitors your server vouches for can chat. See Identity verification.
  • Untrusted input: what visitors write, page context, knowledge passages and tool results reach the agent marked as information, never instructions, and the agent's fixed rules tell it to ignore attempts to change its role or reveal its instructions.
  • Actions: tools that change things can ask the visitor first.
  • Images are decoded and re-encoded before storage (no EXIF, nothing hidden in the file).
  • The agent says it's an AI when asked, and won't identify people from their face or guess sensitive traits.

Rate limits and caps ​

LimitDefaultWhere
Chat connections per IP30 a minuteServer (fixed)
New conversations per IP, per bot30 an hoursecurity.rateLimits.conversationsPerIpPerHour
Messages per visitor12 a minutesecurity.rateLimits.messagesPerMinute
Image uploads per visitor30 an hoursecurity.rateLimits.uploadsPerHour
Message length4,000 characters (the message box stops there too)security.maxMessageChars
Conversation lengthabout 600 messagessecurity.maxTurnsPerConversation (200)
Daily spend, messages, voice minutesnonesecurity.caps
Voice conversations at once5 per botsecurity.caps.concurrentVoiceSessions
Camera framesabout 2 a second per conversation (bursts of 4), 512 KB eachServer (fixed)

Behind a proxy, set TRUST_PROXY=true so per-IP limits see visitors' own addresses, not the proxy's. Spending caps are the main protection against a bot being used heavily on your bill: set them.

Requests to your network (SSRF) ​

HTTP tools, MCP servers (over HTTP), webhooks and the knowledge crawler make requests to addresses admins enter. To keep a bot from being turned against your own network, the server refuses localhost and private, loopback, link-local (including cloud metadata at 169.254.169.254), carrier-NAT, multicast and reserved addresses. It checks the address a host name actually resolves to when it connects, so DNS tricks don't get around it. Only http and https are allowed, and at most 3 redirects are followed (each checked the same way).

  • Allow private network on one HTTP tool lets that tool reach your internal API.
  • ALLOW_PRIVATE_NETWORK=true lifts the rule for everything (tools, MCP servers, webhooks, the crawler).

stdio MCP servers ​

With ALLOW_STDIO_MCP=true, admins can add MCP servers that run as commands on the server. Each gets a minimal environment (PATH, HOME and the like) plus the variables the admin enters, never the server's own settings and keys. But a command can do anything the server's user can, so this is shell access for anyone with the admin role. Leave it off unless every admin is trusted with that.

Production mode ​

Run with NODE_ENV=production (the Docker image does). In development mode the server also accepts the chat's WebSocket from localhost pages, allows http:// webhook URLs and serves source maps.

Wireface Chat 0.1.0. These docs are served by your own server.