Skip to content
sandadocs

Permissions and approvals

What each MCP permission allows, who can grant it, how to make risky agent actions wait for a person, and where every action is recorded.

An assistant connected to sanda can do only what its credential's permissions allow. Permissions are called scopes. sanda checks them on every call, a person grants them on purpose, and the few actions that cannot be undone can be made to wait for an owner or admin before they run.

Scopes

A credential is an integration token or a connected app such as Claude. Each holds a list of scopes. Asking questions of the semantic fluid is the baseline, and every other scope adds one kind of action.

A tool the credential may not use is absent from the tool list, not present and refusing, so an assistant never tries what it cannot do.

There are twelve scopes, in three kinds:

Kind Scopes Who can grant
Reading fluid:read, query:run, workspace:read Any member
Adding rows warehouse:append Any member
Privileged sql:run, sql:write, fluid:write, workspace:manage, warehouse:write, warehouse:model, search:manage, reports:deliver An owner or admin only

warehouse:append is the one write any member can grant, and it is safe for a reason: it reaches only the tables an owner or admin has opened for intake, and it can only add rows to them. It cannot create, replace or delete anything.

A wider scope includes a narrower one. sql:run includes query:run, which includes fluid:read. sql:write includes sql:run and workspace:read. fluid:write includes fluid:read. workspace:manage, warehouse:write, warehouse:model and search:manage each include workspace:read. warehouse:append includes fluid:read. reports:deliver includes nothing else, because sending a report is not asking its questions. The full list, with every tool each one allows, is in scopes.

Who can grant what

Where the permission is granted Who The rule
The consent screen, for a connected app Any member of the workspace except a reader A person can grant only the scopes the app asked for, and fewer if they untick some. A privileged scope is greyed out unless they are an owner or admin
Settings · Integrations, for an integration token An owner or admin They can turn on any switch

The privileged scopes and warehouse:append start unticked on the consent screen. A client that asks for everything is shown everything, and the person opts in to each one that writes. sanda enforces the rule on its own side as well as on the screen: a scope a person's role may not grant is dropped from the grant even if the request names it.

A person with the reader role cannot connect an assistant at all.

Privileged scopes follow the person

A privileged scope lasts only as long as the person who granted it is still an owner or admin. sanda reads their current role on every call. If they are moved to member or viewer, the privileged scopes on the tokens and connected apps they made stop working, the rest keep working, and Settings · Integrations marks the row "permissions inactive". A credential also stops working entirely when the person behind it leaves the workspace.

A closed workspace is read-only for everyone. Every credential keeps only the reading it already had: asking questions and seeing connections if it could do those before. A credential that could only add rows to intake tables or send reports can no longer do either, and closing a workspace never lets a credential read more than it did.

Approvals

A workspace can ask for a person to approve the few things an agent can do that sanda cannot undo. It is off by default, so a client that worked before keeps working exactly as it did until an owner or admin turns approvals on.

Turn approvals on

  1. Open Intelligence · Agents. Only an owner or admin sees the Approvals panel.
  2. Press Ask before an agent acts. The panel now shows how many actions are waiting.
  3. To stop asking, press Stop asking. Anything already waiting stays in place, to be approved or declined. New calls run straight through.

The switch applies to every integration token and every connected app in the workspace. It does not apply to people using the console: a person who drops a view in the explorer is never asked to approve themselves.

What waits

Call Held when
execute_sql It runs in write mode, which is the default. read mode is never held, because looking before deciding is what it is for
drop_view Always, because it drops a view, materialized view or procedure and its rows go with it
drop_search_service Always, because it deletes the index and rebuilding costs a full first build
create_delivery and update_delivery A recipient's email domain is not one your members use. A report emailed to someone cannot be recalled

Everything else an agent can do runs as normal. Approval is a brake for the handful of acts that cannot be undone, not a second consent screen for every write. If you want a person in front of every definition, leave fluid:write off, and the tools that write the fluid are not offered at all.

What the agent sees

The tool answers with an ordinary result, not an error, that says it has not run, why it is waiting, and an id. The agent is told to call action_status with that id, and never to report the action as done until action_status says it ran. A result rather than an error is deliberate: a client that reads an error as "try another way" is exactly the one that must not go looking for another way.

  • A call sanda could not have run anyway (a missing why, a second statement, an unknown warehouse) is refused in the tool's own words and never queued.
  • Sending the identical call again while it waits returns the same id. It does not queue a second one or email anyone again.
  • A workspace holds at most 50 waiting actions. Beyond that, calls are refused until some are decided.

action_status is available to a credential that holds a scope a held tool needs (sql:write, warehouse:model, search:manage or reports:deliver). An agent sees its own credential's actions and nobody else's. Called with no id, it lists the ten most recent.

Decide

sanda emails the workspace's owners and admins when an action is held, since either can decide it. The email names the credential, the tool, why it is held and what would run. It is not sent when Send alert emails for this workspace is switched off in Settings · Plan & budget, and the action still waits on the Agents page. The extra addresses under Also send to are not emailed, because they cannot approve anything.

Owners and admins can decide. On Intelligence · Agents, each waiting action shows:

  • the tool, whether the credential is an integration token or a connected app, its name, and who it acts for;
  • when it was asked and when it expires;
  • why it is held, and the agent's own stated reason where the tool takes one;
  • everything that would run: the whole statement for SQL, the object's name and warehouse for a drop, or the full input otherwise.

Read all of it, then press Approve and run or Decline. A member does not see the queue.

What happens when you approve

  • The action is claimed in a single step, so it runs at most once however many people press the button at the same moment.
  • sanda checks the credential again. If it has been revoked, has expired, acts for someone who has left the workspace or is no longer an owner or admin, or no longer holds the scope the tool needs, or if the workspace is suspended or closed, the action does not run, and the reason is recorded.
  • Otherwise the stored input runs through the same handler the original call would have reached, as that credential. The audit record names the credential and the person it acts for, exactly as it would have without approval.
  • What the tool answered is recorded, and it is what action_status returns.

The panel shows each outcome as a label:

Label Meaning
ran It was approved and the tool answered
ran · answered no It was approved and ran, and the tool answered no, for example because a view did not exist
not run · credential changed It was approved, but the credential could no longer act
declined An owner or admin declined it, and it did not run
expired No one decided within 24 hours. It never runs
running It was approved and is running now
no outcome recorded It started and sanda never recorded how it ended, so check the warehouse before asking again

Decided actions stay in Decided in the last 7 days, with the outcome.

Anything not decided within 24 hours expires and never runs. If it is still needed, the agent asks again and it waits again.

cherry has its own rules

cherry, sanda's agent in the console, is not MCP and does not use this queue. It asks before actions of its own, on its own terms. See cherry actions and approvals.

What is recorded

  • Every tool call and resource read is recorded with the credential, the tool, when it happened, how long it took and whether it answered no. Intelligence · Agents shows them on the Calls tab, and groups them into sessions. The record is of the call and how it went, not the rows that came back.
  • Every refusal is recorded separately. Refused lists calls sanda declined to run at all: an unknown tool, a scope the credential does not hold, a protocol the client got wrong.
  • Every change an agent makes goes through the same handler the console's button runs, with the same validation, so it lands in the audit trail as a console change does. Statements run with execute_sql are kept with the statement and the reason the agent gave.
  • Every step of an approval is recorded: held, approved, declined, run, refused.
  • Creating and revoking a token, and granting an app, are recorded with who did them.

Choosing permissions

Start with nothing beyond asking questions and add only what a job needs.

The job Grant Notes
An assistant that answers questions Nothing beyond the defaults Sees the fluid, runs composed queries and searches text
Also says how fresh the data is workspace:read Lists connections and warehouses. Never a credential
Also refreshes data before it asks workspace:manage Starts a sync, which costs compute like any other sync
An agent that models the fluid fluid:write Definitions go live at once, and approvals do not hold them. Keep fluid:write off if you want a person to make every change
A person logging their day by talking to an assistant warehouse:append only On a table an owner or admin has opened for intake. Nothing else is reachable
A weekly board pack by email reports:deliver Turn approvals on, so a recipient outside the email domains your members use waits for an owner
An agent that builds and schedules views warehouse:model Every build runs on your compute and shows on your bill. See usage
An agent that can run its own SQL sql:run first Read-only. Move to sql:write only with approvals on, because it commits with no undo

Next steps

Something unclear or out of date? Tell us, and we will fix the page.