Access rules#
Every Grist document can be shared with others
using the Manage Users
option in the sharing
menu ().
Users can be invited as Viewers, Editors, or Owners (see
Sharing a document for a refresher on those roles), or a document can be shared publicly with view or edit permissions.
Sometimes, you need more nuance about who can see or edit individual
parts of a document. Access rules give us that power.
Only the owners of a document can edit its access rules.
When a document is loaded, owners see a tool called
Manage Users
option
of the sharing menu
with the Open Access Rules
button (available only to document Owners).
Suppose we run a small business sourcing and delivering unusual objects,
organized using a document with two tables, Orders
and Financials
.
Now we are taking on more employees, and want to share the document with them while
limiting their access to just what they need.
Default rules#
To see the access rules for a document, visit its access rules page by
clicking
Default Rules
for our document:
These rules say, in summary, that Owners and Editors can do anything within the document, that Viewers can only read the document, and everyone else is forbidden all access. These rules cannot be modified, but they can be overridden. To understand whether a group of rules allows a certain permission (Read, Update, Create, Delete, or Structure), read the rules from top to bottom, and find the first applicable rule that allows (green) or denies (red) that permission. We’ll see plenty of examples as we go.
Lock down structure#
By default Owners and Editors are equally powerful within a document, with the ability to create or delete tables or columns, write formulas, reorganize pages, and so on.
Suppose we want only the original Owners of the document to be allowed to change its structure, as we plan to invite other specialized collaborators as Editors. To do this, uncheck the box for the first rule listed under ‘Special Rules’ to disallow editors from editing structure.
Once we’ve made changes, the SAVE
button becomes an inviting green. We
click SAVE
for the rule to take effect.
Important. This is an important first step for any document where you intend to block any access to Editors.
Without denying them the structure permission (S
), anyone with edit access will be able to
create or change formulas. Since formula calculations are not limited by access control rules,
a determined user could use them to retrieve any data from a document. To protect against
that, deny structure permission to users whose access should be limited.
Make a private table#
To ensure that only Owners can access a table, such as the Financials
table in our example,
we click Add Table Rules
and select the table name, Financials
. This creates a new empty
group of rules called Rules for table Financials
.
Then we add a condition for any user who is not an Owner (user.Access != OWNER
), with all
permissions denied. Selecting Deny All
from the drop-down beside R
U
C
D
is a fast
way to set all permissions to denied, or you can click each permission individually to turn
them red. R
is Read, U
is Update, C
is Create, and D
is Delete
(see Access rule permissions).
Structure (S
) permissions are not available at the table level.
Once you are done, click SAVE
.
Now we could go ahead and share the document with a team member
specialized in deliveries, for example. We share the
document with them as an Editor so that the restrictions
we’ve set up apply to them. They won’t see the Financials
table in the
left side bar, and attempts to open it will be denied:
Seed Rules#
When writing access rules for specific tables, it is fairly common to repeat the same rule across many tables —
for example, always grant owners full read and write permissions. To automatically add a set of rules to all
new table rules, you can write “seed rules.” There is a checkbox above default rules that makes the common
case easier with one click. Click it to write a seed rule that will automatically grant owners full access
whenever table rules are added. Click the >
icon to uncollapse the seed rules table to modify seed rules.
Restrict access to columns#
We can restrict a collaborator’s access to columns. In our eample, we might
wish to give a delivery specialist more limited access to
the Orders
table. Perhaps they don’t need to see an Email
column,
or a Piece
column with details of what is in the parcel.
Click Add Table Rules
and select Orders
to create a rule group for the Orders
table.
Now, in the Rules for table Orders
group, click the three-dot icon (…), and
select Add Column Rule
:
In the Columns
area we have a new [Add Column]
dropdown to add all the columns
to which we want the rule to apply (in our case Email
and Piece
).
For the condition, we could use user.Email == 'kiwi@getgrist.com'
. This checks
for the email address of Kimberly, our fictional delivery specialist; we
could also check by name or a numeric ID. We turn all available permissions off for
this user on these columns:
Now that the rules are ready, click Save
.
If we have another employee who specializes in sourcing objects, and who needs to
see a different set of columns, we can do that. For example here we add a
rule to withhold Address
and Phone
columns from user Charon
:
View as another user#
A convenient way to check if access rules work as expected is with the View As
feature,
available in the View As
dropdown. This allows an Owner
to open the document as if they were one of the people it is shared
with, to see what their colleague would see. The Owner does not
“become” that colleague - any changes they make will be recorded as
coming from themselves and not the colleague - but they do see the
document from the colleague’s perspective.
In our example, we could select Kiwi, and the
document reopens, with a large banner stating that we are viewing it
as Kiwi. The Piece
and Email
columns are missing,
and the Financials
table is surpressed:
You can also check in Raw Data to confirm only the expected tables, columns, and rows are exposed.
When satisfied that everything looks as expected, we click the green View as Yourself
button to close this preview, and the document will reload.
User attribute tables#
If we are successful and hire many sourcing and delivery people,
then adding them one by one to rules would be tedious. One solution
is to use “user attribute tables.” You can add a table to your document
that classifies users as you like, and then use those classes in your
access rules. For example, we can make a table called Team
, and give it two
columns, Email
and Role
, where Role
is a choice between
Sourcing
and Delivery
.
Now we can tell Grist to make information from this table available
for access rules, by clicking on Add User Attributes
.
Give the attribute any name you like (this will be how we refer to it
in formulas), such as Team
. Pick the table to read (Team
also in
this case). Give a user property to match against
rows in this table - in our case we’ll use user.Email
. And the
column to match against, Email
.
Save that. Now we can update our rules to be more general. We find with
autocomplete that we have a new user.Team
variable available in
condtions. It makes columns from the Team
available, such as user.Team.Role
.
Now we can check if the user has a particular role, and apply the permissions
that go with that:
Great! Doing a spot check, Charon sees the expected columns for someone in
Sourcing. And if we recruit someone else to work with them, we can just add
them in the Team
table, no rule changes needed.
Row-level access control#
In our example, as orders are processed, they move from sourcing to delivery phases.
So there’s really no need for the two groups to see all the orders at once. Let’s add a
column called Stage
that can be set to Sourcing
or Delivery
, so that we
can update access rules to show only the relevant orders.
In the Rules for table Orders
group, click the three-dot icon (…), and
select Add Default Rule
to add a rule that isn’t limited to specific columns.
Let’s deny access to all rows for non-Owners as a starting point, then add back in the
ones we want. We can do that with the condition user.Access != OWNER
with
Deny All
permissions. Then, we add another default rule by clicking +
, and
add the condition user.Team.Role == rec.Stage
. The rec
variable allows
us to express rules that depend on the content within a particular record.
Here, we check if the Stage
column of a record matches the user’s role.
If it is, we allow R
Read access:
Here’s how the table looks now as Kimberly (doing deliveries):
And here’s how the table looks as Charon (doing sourcing):
Kimberly and Charon now have read-only access to the table. Owners still have full write access to all rows and columns.
Understanding reference columns in access rules
You can limit the data team members access to just those rows pertinent to their work. One way to do so is to relate all records in all tables to their respective team members. For example, leads and sales records can reference the sales rep responsible for those records. This quick video explains how.
Checking new values#
Access rules can be used to permit only certain changes to the document.
Suppose we want Delivery
people
to be able to change Stage
from Delivery
to Done
, without giving them the
arbitrary rights to edit that column. We can grant them that exceptional right
as follows.
In the Rules for table Orders
group, click the three-dot icon (…), and
select Add Column Rule
. Set [Add Column]
to Stage
, and mark the U/Update
permission to be granted. For the condition, use this:
(user.Team.Role == 'Delivery' and
rec.Stage == 'Delivery' and
newRec.Stage == 'Done')
This checks if the user has the Delivery role, and the record is in the Delivery stage,
and that the user is trying to change the Stage to Done
. The newRec
variable is a
variant of rec
available when the user is proposing to change a record, with rec
containing its state before the change, and newRec
its state after the proposed change.
Now, if we view the table as Kiwi, and try to change a Stage
to Sourcing
, we are
denied:
If we change a Stage
to Done
, it works, and the record disappears from view since
it is no longer in the Delivery
stage:
Link keys#
Sometimes it is useful to give access to a specific small
slice of the document, for example a single row of a table. Grist offers
a feature called “link keys” that can help with that. Any parameters in
a Grist document URL that end in an underscore are made available to
access rules in a user.LinkKey
variable. So for example if a document
URL ends in ....?Token_=xx-xx-xx-xx&Flavor_=vanilla
, then user.LinkKey.Token
will be set to xx-xx-xx-xx
and user.LinkKey.Flavor
to vanilla
.
Let’s work through an example to see how that can be helpful.
Suppose we have a table of Orders
and we’d like to occasionally
share information about a single order with someone. To do that with
link keys, we need some kind of hard-to-guess code for each order,
which can be used to access it. Grist has a UUID()
function that
gives a unique, random, and hard-to-guess identifier, so let’s add a UUID
column with
formula =UUID()
:
In fact we want UUID()
to be called just once per order, when we create
it, and never recomputed (because then it would change). So in the right sidebar
we convert the formula column to a data column, freezing its values:
This converts our formula to a trigger formula. We set the formula to apply to new records:
At this point we have a solid hard-to-guess code for each order in the
UUID
column, that will be created as we add new orders. It can
be handy at this point to construct links to the document with that
code embedded in them. Grist has a helper for this called
SELF_HYPERLINK
. To add a
link key called <NAME>
, just use this function with a
LinkKey_<NAME>
argument. In our case, we pass LinkKey_UUID=$UUID
to
embed the value of the UUID
column into the URL. We also set label=$Ref
to control the text label of the link in the spreadsheet. To show the link,
we set the column type to Text
and set the HyperLink
option:
Once we have these links, we can tidy up a little by hiding the
UUID
and Ref
columns (see Column operations for a refresher on how
to do this):
The links don’t do anything special yet, but we have everything we need to make that happen now. Here is an example of access rules to allow anyone with a UUID in their URL to read any order with a matching UUID (otherwise only owners can read orders in this case):
And here is what a non-owner now sees, with the UUID of the first order in their URL:
This is just the beginning of the possibilities. Link keys can give access to multiple rows across many tables. They can be used in User attribute tables. And the data they give access to can be within tables, cards, card lists, charts, and custom widgets.
Check out another example to deepen your understanding of link keys even more.
Access rule conditions#
Accress rule conditions contain a formula expressing when the rule should apply. A blank condition will always apply. When a condition applies for an action, the permissions associated with the condition are set to allowed or denied for that action if no earlier rule in the same group has yet set them. When a condition does not apply, no permissions are set by that rule, but other rules could set them.
Formulas are written in a restricted subset of Python.
Variables that may be available in access rules are user
, rec
, and newRec
.
The user
variable contains the following members:
user.Access
: one ofowners
,editors
, orviewers
, giving how the document was shared with the user (see Sharing a document).user.Email
: the email address of the user (oranon@getgrist.com
for users who are not logged in).user.UserID
: a numeric ID that is associated with the user.user.Name
: the user’s name (orAnonymous
if unavailable).user.LinkKey
: an object with any access control URL parameters. Access control URL parameters end in an underscore (which is then stripped). Only available in the web client, not the API.user.SessionID
: a unique string assigned to anonymous users for the duration of that user’s session. For logged in users,user.SessionID
is always"u"
+ the user’s numeric id.
For an example of using the user
variable, read Default rules.
The rec
variable contains the state of an individual record/row, for
conditions that need to take that into account. When it is used, that
rule becomes row-specific. That allows, for example, to make certain
rows visible only to certain users, or to prohibit modification of
certain rows by certain users.
For an example of using the rec
variable, read Row-level access control.
The newRec
variable is available for record/row creation and
updating, and contains the state of a row after a proposed change,
allowing you to selectively allow or deny certain changes.
For an example of using the newRec
variable, read Checking new values.
Supported operations in condition formalas are currently: and
, or
,
+
, -
, *
, /
, %
, ==
, !=
, <
, <=
, >
, >=
, is
, is
not
, in
, not in
. Supported variables are: user
, rec
,
newRec
with their members accessed with .
. Strings, numbers, and
lists are also supported. If an operation you need is not available,
consider whether you can do part of the work in a formula in the table
itself (see Access rule memos for an example).
Comments are allowed, using #
or """
. If there is a comment in a
rule, then the first comment in a rule that results in a denial of an
action will be reported to the user as a tip for why the action was not
permitted. See Access rule memos for an example.
Access rule permissions#
A permission controls whether a user can perform a particalar kind of action. Grist access rules currently deal with 5 kinds of action, which are given single letter acronyms for convenience:
R
- permission to read cells.U
- permission to update cells.C
- permission to create rows.D
- permission to delete rows.S
- permission to change table structure.
The S
structure permission is available in the default access rule
group. Column rules lack the C
create and D
delete permissions,
which should be handled in default table rules.
Note: The S
permission is very powerful. It allows writing formulas, which can access
any data in the document regardless of rules. Since the S
permission is on by default for
Editors and Owners, any such user would be able to edit a formula and so retrieve any data.
In other words, having the S
permission makes it possible to circumvent other rules that prevent
access to data. For this reason, turning it off – as described above in Locking down
structure – is an important first step in limiting data access.
Access rule memos#
When a user receives an error message denying them access because of a rule, it can be helpful to give specific details that will help them understand the problem. You can do this by adding a memo for the condition. First, click the memo icon to the right of your condition.
Type the error message you wish to display into the entry box. Be sure to save your changes.
When the rule blocks a user from performing an action, the memo will appear as a notification.
For an explanation of how this particular Access Rule works, see Access Rules to Restrict Duplicate Records
Access rule examples#
Along with the extended example of using access rules in this section, we will collect complete examples of access rule templates and guides here.
- Lead lists: A very simple list of leads, assigned to individuals to follow up, with control of assignments reserved for document owners.
- Account-based Sales Team: Sales CRM with deals and contacts assigned to sales reps. Reps can only see their own contacts and deals, but managers can see everything.
- Public Giveaway: A public giveaway organizer that uses access rules to enforce giveaway rules without requiring claimants to log into Grist.
- Simple Poll: A simple poll managed in Grist with access rules to limit one response per visitor.
- Crowdsourced List: Publicly crowdsourced list with access rules to empower moderators to edit almost anything, but limit visitors to only making and editing their own contributions.
- Time Sheets: Template to capture contractor timesheets. Access rules permit contractors to view only their historical time sheets, and edit only the active month.
- Project Management: Track tasks by event and flag tasks at risk. Access rules limit permissions by department, and expand managers’ permissions.