TessariDBDocs
  • 0.34.2-betalatest
  • 0.34.1-beta
  • 0.34.0-beta
  • 0.33.4-beta
  • 0.33.3-beta
  • 0.33.2-beta
  • 0.33.1-beta
  • 0.33.0-beta
  • 0.32.0-beta

Grants

A role says which verbs; a grant says which tables — and a user's grants, if they have any, are the whole story.

One sentence carries this whole page:

A user's grants, if they have any, are the whole story, and a user with none is governed by their role.

That is what lets grants exist without changing what any already-declared user may do, and it is what makes them capable of narrowing — a permission system that can only widen is decoration.

DEFINE NAMESPACE prod;
USE NAMESPACE prod;
DEFINE DATABASE shop;
USE DATABASE shop;
DEFINE COLLECTION users;
DEFINE COLLECTION orders;

An editor with no grants may write every table in their database. Give that same editor one grant and they reach exactly one table:

GRANT read, write ON orders TO ada;

They can no longer read users at all. Nothing about their role changed; the grant became the whole answer.

The two verbs

verbcovers
readreading records
writewriting records, and declaring structure on the table

A verb the language does not have is refused where it is written:

GRANT scribble ON users TO nobody;

NoSuchVerb. And so is a revocation of one:

REVOKE scribble ON users FROM nobody;

A grant names a user and a table, and both have to exist:

GRANT read ON users TO nobody;

Unknown — there is no such user.

GRANT read ON nonesuch TO nobody;

Unknown — nor such a table.

Fields

A grant may narrow to named fields as well:

GRANT read ON users FIELDS name, email TO ada;

The same rule applies one level down: what is named is the whole story, and naming nothing names no limit. A grant with no FIELDS reaches every field.

FIELDS goes with read and not with write, and the refusal is deliberate: a whole-record write by somebody who can only see three of a record's eight fields would erase the five they cannot see, which is not a permission anybody means to give.

Revoking will not remove the last one

This is the rule that surprises people, and it is the right surprise. Going from one grant to none does not lock a user out — it widens them, from a named table back to every table their role allows. That is the opposite of what somebody typing REVOKE is thinking about.

So the last one is refused, with LastGrant, and the refusal says how to widen on purpose. Removing a user's access entirely is DROP USER; changing what they reach is another GRANT.

Administering is not something a stranger does

DEFINE USER ada ON prod.shop ROLE editor PASSWORD 'correct horse';
GRANT read ON users TO ada;

NotSignedIn — the store closed when ada was declared, and granting is administering.

The order in which those two checks run is itself load-bearing:

GRANT read, write ON users FIELDS name TO ada;

Also NotSignedIn — not the field rule's own refusal. Identity is decided before the statement's contents are, because a refusal naming the field rule would have told a stranger that their statement parsed, which is a fact they are not owed.

What is deliberately absent

There are no roles you define yourself, no groups, no inheritance and no deny rules. Three roles, two verbs, an optional field list, and one sentence deciding which of the two applies. Everything a deny rule expresses is expressible by granting less — and unlike a deny rule, a grant cannot interact with another grant to produce an outcome nobody predicted.

Grants — TessariDB