Permissions
Groups, the union rule, and what "cannot read" means for an API, an OpenAPI document or an agent. The same rules apply on every surface.
Every read and every write in an app, from the grid, the API, MCP or the built-in assistant, goes through the same permission check. There is no route around it, and no key that skips it.
The model
A builder gives each app groups, and each group its own permissions: on which tables it may do which operations, optionally narrowed to some rows and some fields. A person can be in several groups. Their access is the union of their groups, taken per field and per operation.
There is no order, no deny and no override. Adding a group can only ever add access, and what no group allows, nobody has. No group is special to the platform: there is no admin group in an app. Administration happens in the Studio, on the other plane.
Four questions, answered separately
| Question | Example |
|---|---|
| Which tables | Support cannot see invoices at all |
| Which rows | A rep sees the deals they own |
| Which fields | Nobody outside Finance sees the margin |
| Which actions | Read yes, delete no |
What “cannot read” means
A field you cannot read is absent, not blanked. It is not in the record, not in the schema you are served, not in your OpenAPI document, not in your agent’s tool list, and not named in any error, because naming it would be the very leak the rule exists to prevent. A row you cannot see is answered as if it did not exist.
That is also why an app’s API reference on this site names no table and no field. Each person’s document is generated from their own view of the app. See Why an app has an API of its own.
Filters cannot be used to guess
A filter can only narrow what you would see anyway. One case needs a rule: a field you may read
on only some of your rows (“Finance sees the margin, on won deals”). Filtering or sorting by
it would let you count rows outside your scope, so it is refused with 403. GET /v1/app
lists, per table, the fields you can see but not filter or sort by (constrained), so a client
can grey them out before asking.
Credentials narrow, never widen
A key or an agent connection carries scopes (records:read, records:write, …). Scopes narrow
what a credential may do; they never add to what its person may do. A key with records:write,
made by someone who may only read, still cannot write. See
Authentication.
Before changing a rule
Builders can ask what someone would see, without granting anything. rules.simulate answers
with the rows and fields a set of groups would get, broken down per group so you can see which
group grants what:
POST https://studio.gtable.app/v1/apps/{appId}/rules/simulate