How Alvero handles PHI, tenancy, and trust
Alvero processes protected health information on behalf of dental practices in Canada. This document describes the specific technical controls, operational policies, and architectural decisions that govern how PHI moves through the platform, how tenants are isolated from each other, and where human judgment is mandatory regardless of agent capability.
The threat model we built against
Alvero's security controls were designed against a concrete set of failure scenarios. Understanding what we assumed can go wrong—and why each assumption is plausible in a dental SaaS context—explains why the controls take the form they do.
| Threat | Why it is plausible | Primary control |
|---|---|---|
| Rogue insider | A platform engineer or support agent with database access could read another tenant's financial or patient data. Privileged access is a standard insider threat vector. | Worker-layer tenant isolation; Postgres roles; immutable audit logs; no raw PHI in support tooling. Alvero staff access requires dual approval and is time-limited. |
| Compromised credentials | An owner's session token is stolen via phishing or device compromise. The attacker can reach the platform with a valid JWT. | JWTs are short-lived (1-hour expiry). Kill switches are accessible without password (secondary auth factor). Device session revocation is immediate. |
| Model hallucination acting on PHI | An LLM agent produces a plausible but factually incorrect output (a wrong patient name, amount, or insurance claim number) and that output is sent to a patient or insurer. | Human approval is mandatory on every outbound PHI event via Messenger. Agents draft; humans approve. No agent has autonomous outbound PHI authority. |
| Cross-tenant data leak | A Postgres RLS misconfiguration or a bug in query construction returns one tenant's data in another tenant's API response. | Worker-layer tenant claim validation runs before any database query. RLS is a defense-in-depth second layer, not the primary boundary. |
| Third-party LLM data retention | A cloud LLM provider (OpenAI, Anthropic) retains PHI passed in prompts and uses it for model training. | Zero-retention API contracts with both OpenAI and Anthropic. PHI is never passed in system prompts; structured output contracts minimize free-text PHI in completions. |
Worker-layer tenant isolation
Every HTTP request to the Alvero API passes through a Cloudflare Worker. The Worker's first action is tenant claim verification: it validates the JWT in the Authorization header for signature integrity, token expiry, and tenant-id binding. If the claim is absent, malformed, or expired, the Worker returns 401 and terminates. No database connection is opened. No query is issued.
Supabase Postgres uses row-level security (RLS) with per-tenant Postgres roles as a second layer of isolation. RLS is configured such that a query issued under a given Postgres role can only read rows where tenant_id matches that role's binding. However, Alvero does not rely on RLS as the security boundary for the following reason:
A single RLS misconfiguration—a missing policy, a policy with an incorrect condition, or a new table added without a corresponding policy—can expose all rows in that table to any authenticated query. In a multi-tenant PHI context, a RLS bug becomes a cross-tenant data breach. The Worker-layer enforcement is the boundary: even if RLS returned the wrong rows, the Worker would reject any response whose tenant_id fields do not match the claim it validated. The Worker is also easier to audit than distributed Postgres policies because all tenant enforcement logic lives in a single, version-controlled Worker module.
Signed tenant claims
Tenant claims are RS256-signed JWTs issued at authentication by Alvero's auth service. The claim payload includes: tenant_id, user_id, role (owner / doctor / staff / patient), iat, and exp (1-hour TTL). Workers validate the signature against the auth service's public key, which is cached at the edge with a 5-minute TTL and refreshed on rotation. A rotated signing key invalidates all outstanding JWTs within one cache cycle.
Two-level kill switch
Alvero provides two independently operable kill switches that bypass all agent autonomy and immediately suspend platform activity for the affected scope.
Practice owner kill switch
Each clinic owner can disable their tenant instantly from Flight Deck or via a dedicated emergency URL that does not require a valid session (it uses a secondary TOTP factor). Disabling a tenant suspends all agent execution, blocks all outbound Messenger events, and revokes all active JWTs for that tenant within one Worker cache cycle (≤5 minutes). The tenant's data remains intact; no deletion occurs on kill-switch activation.
Operator kill switch
Alvero's platform operator has a global kill switch that disables all agent execution across all tenants simultaneously. The global switch operates at the D1 control plane level: Workers poll D1 for the global-halt flag and refuse to execute agent jobs when it is set. The global switch does not affect read-only surface access; owners can still log in and view data. The switch is audited with actor, timestamp, and stated reason.
PHI-safe monitoring
Alvero uses PostHog for product analytics. PostHog autocapture is disabled. The client-side PostHog SDK is configured with the following restrictions, applied at initialization:
- Autocapture off: No automatic DOM event capture. Every event is explicitly defined in code and reviewed before deployment.
- Text and input masking: The
maskAllTextandmaskAllInputsflags are set totrue. PostHog records interaction patterns (click, navigate, form submit) but never the content of text nodes or input values. - Session recording off: No session replay is captured. Session replay is incompatible with PHIPA requirements for PHI-handling surfaces.
- Server-side scrubbing: All events pass through a server-side scrubbing layer before ingest into PostHog. Any event property that pattern-matches a known PHI shape (email, phone number, health card format, date of birth) is replaced with a redacted placeholder. The scrubbing layer is deployed as a Cloudflare Worker.
Alvero instruments behavior: which surfaces are used, which flows complete or abandon, where users encounter errors. It does not instrument content: patient names, financial figures, or clinical data are never present in analytics events.
Human approval on every outbound PHI event
The Messenger surface is the only channel through which Alvero communicates with patients via SMS, email, or voice. The rule is absolute: no outbound message containing PHI is sent without an explicit human approval action.
Agents—including Owner Brief AI, Revenue Hunter, and the Voice surface's outbound dialler—may draft messages. These drafts appear in the Staff Portal or Messenger approval queue with the full draft content visible, a PHI classification label, and the agent that produced the draft. A staff member or owner must tap or click an explicit "Send" action for each message. There is no batch-approval or auto-send timer.
The Messenger Worker that calls the Twilio SMS API checks for an approval record before issuing any API call. If no approval record exists for the message ID, the Twilio call is rejected at the Worker level. Agents cannot call Twilio directly; all SMS and voice egress routes through the Messenger Worker. This means even a compromised or malfunctioning agent cannot send a PHI-containing message autonomously.
Inbound messages from patients do not contain Alvero-generated PHI by definition. However, patient replies that contain PHI (e.g., a patient responding with their date of birth) are stored with the same tenant-isolated access controls as all other PHI, and are never forwarded to analytics systems.
The HITL safety ladder (Green / Yellow / Red)
The Per-Tenant Coach agent applies improvements to practice configuration using a three-tier autonomy model. The tier a proposed change is assigned determines whether it executes immediately, runs in shadow mode first, or waits for owner approval. Tier assignment is determined by the change's estimated impact scope and whether it touches PHI-adjacent configuration.
Auto-applies immediately
Low-risk changes that are easily reversible and affect a narrow operational scope. Examples: adjusting a recall reminder interval by ±1 week, updating a posting rule for a recognized vendor category, modifying a report schedule time. Green-tier changes are still logged and visible in the audit trail. Per-Tenant Coach can auto-revert a Green change if Agent Evaluator detects a regression within the 14-day monitoring window.
Shadow mode for 7 days, then auto-applies if no regressions
Moderate-impact changes where the expected benefit is clear but the risk of unintended side effects is non-trivial. The proposed change executes in parallel with the existing configuration for 7 days; outcomes are compared against the baseline. If the shadow run shows no regressions in the tracked metrics, the change auto-applies. If any regression appears, the proposal is discarded and a diagnostic report is surfaced to the owner. The owner may choose to apply a Yellow change before the 7-day window ends by explicitly approving it.
Owner approval required — no timeout
High-impact changes, PHI-adjacent configuration changes, or changes to core financial rules (e.g., posting rule overhauls, chart of accounts structure, close-period parameters). The practice owner receives a full description of the proposed change, the pattern data that motivated it, the expected impact, and a rollback plan. The proposal waits indefinitely. No auto-apply occurs regardless of elapsed time. Owners may reject with or without explanation.
Agent Evaluator and auto-rollback
Every agent change—a new agent version, a Per-Tenant Coach-applied configuration, or a platform-level deployment—initiates a 14-day monitoring window managed by the Agent Evaluator. This is a circuit breaker, not a trust system. The Agent Evaluator assumes every change is potentially harmful until the monitoring window clears without a threshold breach.
Regression metrics tracked during the monitoring window include: posting accuracy (matched vs. review-queued rate), reconciliation match rate, close cycle time, Messenger approval queue volume, and PHI classification accuracy for outbound drafts. Each metric has a configurable threshold; a breach on any single metric triggers auto-rollback.
Auto-rollback reverts the affected agent or configuration to its prior version without human intervention. The rollback action itself is logged immutably. The owner and Alvero's platform team receive an immediate notification with the specific metric that triggered rollback. If the prior version also fails regression tests, the Agent Evaluator suspends the affected agent and escalates to Alvero's platform team for manual review—no further autonomous action is taken.
Sub-processor list
The following sub-processors handle data on Alvero's behalf. The authoritative, current list is maintained at alvero.dental/trust/.
| Sub-processor | Role | Data category | PHI exposure |
|---|---|---|---|
| Cloudflare | Edge runtime, Workers, D1, R2, KV, Queues | All platform traffic; document storage; control state | PHI in transit and at rest in R2. Cloudflare DPA with CA-Central data handling provisions. |
| Supabase | Postgres database | All tenant financial data, agent outputs, audit logs | PHI in database (tenant financial records may reference patient IDs). CA-Central region. Supabase DPA executed. |
| Stripe | Payment processing | Practice subscription billing; merchant settlement data (read via webhook) | No patient PHI. Practice billing data only. Stripe is PCI-DSS Level 1 certified. |
| Plaid | Bank and card data aggregation | Practice bank transactions, balances, statement metadata | No patient PHI. Financial institution data for the practice entity only. |
| Twilio | SMS and voice messaging | Outbound SMS drafts (post-approval), inbound SMS, voice call routing, transcripts | PHI possible in approved outbound messages and transcripts. Twilio BAA executed. Transcripts stored in Alvero R2, not in Twilio storage. |
| OpenAI | LLM inference | Agent prompt completions (document extraction, posting classification, brief composition) | Structured inputs; free-text PHI minimized by design. Zero-retention API contract in force; OpenAI does not use Alvero data for model training. |
| Anthropic | LLM inference (secondary, specific agent tasks) | Agent prompt completions | Same policy as OpenAI. Zero-retention API contract in force. |
| PostHog | Product analytics | Behavioral event data (interactions, navigation, feature usage) | No PHI. Autocapture disabled; text masking enforced; server-side scrubbing before ingest. See PHI-safe monitoring. |
Data residency
Alvero's primary data residency is Canada. All Supabase Postgres instances are deployed in the ca-central-1 region. All Cloudflare R2 document buckets are configured with Canadian regional storage. Cloudflare D1 control plane data is stored in a North American region nearest to the tenant; practices can request CA-only D1 placement.
LLM inference calls (OpenAI, Anthropic) route to the providers' API endpoints under zero-retention contracts. Neither provider retains prompts or completions beyond the API call. Inference endpoints may be in US regions; under the zero-retention contracts, no data persists beyond the API call duration. Practices subject to PHIPA provincial requirements are advised that zero-retention contracts do not constitute Canadian data residency for LLM calls—data crosses the border for the duration of the inference request. This is disclosed at onboarding and in the BAA.
Audit logs
Every consequential action in the Alvero platform is logged immutably to the audit_events table in Supabase Postgres. The log schema captures:
- Event type — agent action, human approval, kill switch, Messenger outbound, QBO export, HITL decision, Per-Tenant Coach application, Agent Evaluator rollback
- Actor — user_id (for human actions), agent_id + version (for agent actions), "system" (for automated platform events)
- Tenant ID — every log record carries the tenant_id; cross-tenant log queries are not possible through the API (Worker enforcement)
- Timestamp — UTC, microsecond precision
- Payload hash — SHA-256 of the action payload; the payload itself is stored in R2 with a reference in the audit record. The audit table stores hashes, not raw PHI.
Audit logs are append-only at the Postgres role level: the application role has INSERT privilege on audit_events and no UPDATE or DELETE privilege. Log export is available to practice owners in CSV or JSON format from the Bookkeeper AI surface, scoped to their tenant.
Right to be forgotten
Alvero supports data deletion requests under PIPEDA, PHIPA, and GDPR Article 17 (for practices with EU patient populations). The deletion process operates across all data stores and sub-processors:
- Request intake: Deletion requests are submitted via the practice owner (for patient data) or directly by the practice owner (for full practice data export and deletion). Requests are logged in the audit trail at intake.
- Scope determination: Patient data deletion covers all records referencing the patient_id in Supabase Postgres, all documents in R2 with that patient_id in the access path, and all Messenger threads linked to that patient. Practice data deletion covers all 14 agent outputs, the full audit log (exported first), all Bookkeeper AI financial records, and all R2 documents for that tenant.
- Agent suspension: All agents for the affected scope are suspended before deletion begins. This prevents any agent from writing new records referencing the subject during deletion.
- Postgres deletion: Records are hard-deleted (not soft-deleted) in dependency order to respect foreign key constraints. Audit log records referencing the deleted subject are retained as required by PHIPA (7-year retention obligation for audit records) but the payload R2 objects are deleted, leaving only the hash in the audit record.
- R2 deletion: All R2 objects in the tenant-scoped path (or patient-scoped path) are deleted using the R2 delete API. Cloudflare's R2 deletion propagates across storage replicas within 24 hours.
- Sub-processor notification: Sub-processors that may hold the subject's data (Twilio for message logs, PostHog for any behavioral data) are notified. PostHog provides a user deletion API; Twilio message logs are deleted via the Twilio message delete endpoint.
- Confirmation: A deletion completion record is issued to the requester with the scope, timestamp, and a list of sub-processors notified. This record does not contain PHI.
Full documentation of PIPEDA, PHIPA, and GDPR commitments is maintained at alvero.dental/trust/.