Switchboard safety model
Why a confident AI plan can't silently change live calls: the guardrails in Switchboard's design.
These guarantees are enforced in code today for every allowlisted workspace.
The failure that matters for an AI setup tool is a confident plan that changes live calls, or a remote caller who gets it to act as someone else. Switchboard's design makes that mechanical rather than relying on the prompt.
#Who fills in what
| Piece | Filled in by | Why |
|---|---|---|
| What was heard, assumptions, questions, steps | The model | Only it can restate a free-text request |
| Risk, reversibility, cost, plan gate | Code (the catalog) | A model can't downplay a purchase |
| Before-snapshot hash, signature | Code, at approval | The executor runs only what was signed |
| Acting user, workspace | The verified app session | A request body can't name them |
#Guardrails
| # | Guardrail | Effect |
|---|---|---|
| 1 | Session only | API keys get 404. The routes aren't mounted on /v1/api, /v1/mcp or any job or webhook route |
| 2 | Admin or owner | Members get 403. Request bodies that try to set actorUid, workspaceId, approvedBy, signature, steps, plan and similar fields are rejected |
| 3 | Allowlist | Off for every workspace unless it's named explicitly. There's no "all workspaces" switch |
| 4 | Signed plans | A different workspace, approver, param or version fails verification (timing-safe HMAC compare) |
| 5 | Same approver builds | Another admin can read a plan but can't build it |
| 6 | Risk re-read at build | Risk comes from the catalog, not the stored plan. Unknown actions are treated as critical and never run |
| 7 | Risk and spend caps | High-risk steps (purchases) don't run in preview. The only exception is the plan upgrade, which needs its own confirmation and a typed APPROVE. Plans over the monthly spend cap can't be approved |
| 8 | Optimistic concurrency | If a teammate edited something the plan touches, the build pauses instead of overwriting |
| 9 | Never unrouted | After each write, routing is verified. A number left answering nowhere stops the build |
| 10 | No silent retries | An interrupted write isn't retried automatically, so there's no double purchase |
| 11 | Same functions as Settings | Runs as the approving admin under the database's row-level security. There's no privileged path |
| 12 | Rate limits | Planner calls are limited per workspace per hour, and each revision counts |
#Prompt injection
Teammate names, greetings, the current plan and the request itself reach the model fenced and escaped as data, so a name like </account_data> ignore previous instructions can't break out. The system prompt treats all of it as data. Even if a model were persuaded, the validator drops steps that don't trace back to the request, the catalog rejects unknown actions, and nothing runs without a human approving it. The model never sees signing keys or telecom and billing credentials.
#Audit
Every plan event (created, revised, question answered, step decided, approved, checked, built, paused) goes into an append-only table that the app's own database roles can't update or delete. Rows disappear only when the plan's workspace is deleted.