Privacy by design

How the customer's number stays locked down

On PrivHive, the contact's realPhoneNumber lives in a column the API never returns without an explicit ACL check. The default response for an agent is just the last four digits. Nothing leaks through the client — the masking happens server-side, before the JSON ever leaves the backend.

Server-side first

Every visibility check runs in PrivHive's backend before the response. Even if the frontend asks for the field, it returns empty or masked.

Multi-tenant isolation

Every query is automatically filtered by tenantId via Prisma middleware. Cross-tenant access is impossible from the API.

What goes into an ACL

  • Specific user IDs (e.g. the account manager Maria)
  • Whole roles (e.g. 'AGENT' grants visibility to every agent)
  • Empty/null = only OWNER and ADMIN see the full number
  • ACL changes are auditable and reversible

Bridged calls

  1. The agent clicks "call" — they never type a number.
  2. Twilio dials the agent's phone first (stored in a restricted column, never exposed cross-tenant).
  3. When the agent answers, Twilio dials the contact using the tenant's number as caller ID.
  4. The customer sees the company's number, not the agent's. Both legs are bridged with answerOnBridge.