Skip to content

Security

Domain allowlist

The widget-id attribute in the embed snippet is public. It contains no credentials and is safe to commit to source control, deploy to a CDN, or serve to any visitor.

Access control is enforced server-side on every request:

  1. The Powsoo API reads the Origin header of every /v1/voice-tokens and /v1/embed/*/config request.
  2. It validates the origin against the widget’s Allowed origins list, configured in the dashboard.
  3. A request from an unlisted origin is rejected with 404 widget_unavailable before any token is minted or credentials are accessed.

This is the same model Stripe (publishable keys), Segment (write keys), and Behold use. The public identifier is useless without a matching origin.

PatternExampleMatches
Bare domainexample.comhttps://example.com only
Wildcard subdomain*.example.comAny subdomain
Portlocalhost:5173Exact port match

localhost and 127.0.0.1 are always allowed without any dashboard configuration.

Credential encryption

When an agency connects their Retell or Vapi API key, Powsoo immediately encrypts it with AES-GCM before writing to Supabase. The encryption key (VOICE_PLATFORM_KEY_SECRET) lives in Cloud Run’s Secret Manager, not in the database.

The plaintext API key:

  • Is never written to Powsoo’s database or logs
  • Is decrypted in memory only at token-mint time, then discarded
  • Uses a per-user AAD (Additional Authenticated Data) so ciphertexts are not portable between tenants

Session tokens

After a voice token is minted, the API issues a sessionToken (sst_*) — a 24-byte random string bound to the callId. This short-lived token authenticates the SSE stream subscription and the result POST for that specific call. It has a ~10-minute TTL and is scoped to one call session.

The session token is never stored in the URL, never sent to Retell, and is cleaned up when the call ends.

No PII by default

Powsoo does not persist card field values (emails, phone numbers, addresses) in its database. Only structural metadata is stored:

  • That a card was shown (type, timing)
  • Whether the user confirmed, edited, or skipped
  • Call duration and session metadata

Raw field values transit Powsoo’s API during the tool-call relay but are not written to any store. Full session replay is available at the Enterprise tier under a separate Data Processing Agreement — it is off by default.

Audio never transits Powsoo

Audio flows direct widget ↔ Retell/Vapi over LiveKit WebRTC. Powsoo’s API is never in the audio path. A Powsoo outage cannot affect in-progress voice audio.

Reporting a vulnerability

Email security@powsoo.com. We aim to respond within 48 hours.