Permission recipes
Emu Watch, worked end to end — private-by-default volunteers, a public map, the Coastal Volunteers, the Rangers, and a rule that beats everything.
#How to use these
These recipes build Emu Watch piece by piece: Sam's sightings log, Priya's records, Ben and Ana, the Coastal Volunteers, the Rangers, the public map, and the sensitive nesting sites. Read in order they assemble the whole site; read alone each one stands on its own.
Flocks are crews in the API, and your Nest — the site you sign in to — is a
project there.
Each recipe says what you want, what to set, and — importantly — what it does not do. That last part is where most permission bugs come from: a setup that looks right for the case you tested and is wrong for the case you did not.
Every one of them rests on the one sentence. If a recipe does not behave the way you expect, walk that sentence — role, then reach, then never-rules — before changing anything.
#1. The Emu Watch baseline: volunteers log their own, private by default
People sign up and log sightings. Priya's hundred sightings are hers, and Ben sees none of them.
Set up
| Role | Sees on its own | Write | Why |
|---|---|---|---|
volunteer |
Own | yes | Their own sightings, fully theirs |
public |
None (for now) | no | Recipe 2 opens the map |
"Own" is the whole trick. Nothing had to be hidden, because nothing was ever open — Priya's sightings are private by default, not by her diligence.
What this does not do
It does not stop a volunteer reading another volunteer's sightings if the row scope is All rather than Own. If volunteers should only see their own, the scope must be Own — the write permission is not what hides them.
#2. Publish the map: one standing rule, not five hundred shares
Some sightings belong on the public map, which is where the "This season" report reads from. Nobody should be publishing sightings to it one by one — one rule should do it, forever.
Set up
Open the sightings collection, go to Settings → Access, and under Who else can see these records add a rule:
Anyone (not signed in) can view records where status is verified
That is the whole recipe. It applies automatically to every sighting that matches, now and later — a ranger marks a sighting verified and the rule does the rest. Nobody has to remember anything per sighting.
Volunteers see their own AND the verified ones
They already do. A volunteer's own reach ("records they created") and this rule are separate reasons to see a sighting, and any one of them is enough — so a volunteer sees their own unverified records plus everything verified, with no second rule to write. Add another rule only when a different audience needs different records.
Two audiences, two rules
"Verified OR historic" is not one rule with an or in it — it is two rules,
each with its own condition. That is why the builder has no and/or groups to
get lost in.
What this does not do
It does not decide who may set status — with only this rule, any volunteer
could verify their own sightings by editing the field. That is recipe 3, and the
two belong together.
#3. Only rangers may verify
Volunteers log; the Rangers decide what the public map shows. "Verifying" is a value in a field, so it is controlled by a field rule, not by who can reach the row.
Set up
On the volunteer role, for collections/sightings, set:
- a preset of
status = unverified, which forces the value on create; - a validation rule of
status = unverified, which refuses any write that would leave it as anything else.
Give the ranger role neither, so it can set the field freely.
Why both. The preset alone stops Priya choosing a status when she logs a sighting. The validation rule is what stops her changing it afterwards — without it, she logs an unverified sighting and immediately edits it to verified.
What this does not do
It does not hide the field. Volunteers still see status; they just cannot move
it. Hiding a field from reading is a separate setting (the column allow-list).
#4. A private group: a flock that sees its own work
Priya starts the Coastal Volunteers and invites people.
Set up
- Create a flock and invite the members — Ben as a viewer, Ana as an editor.
- Members share their sightings with the flock as they see fit.
The flock places then do the grading for you, with no extra configuration:
| Flock place | Can |
|---|---|
viewer |
See what is shared with the flock |
editor |
See and change it |
admin |
All of that, plus manage the flock itself |
What this does not do
It does not make flock members equal. Ben, a viewer, cannot edit the season even though Priya shared it at Edit level — a flock share gives each member the lower of the share and their place in the flock. See sharing an item.
#5. The same person, different standing in different flocks
This is the case most systems get wrong, and it is worth testing deliberately.
Ana is an editor in the Coastal Volunteers and a viewer in the Rangers.
Set up: nothing special. Add Ana to each flock at the appropriate place.
What happens: Ana edits what is shared with the Coastal Volunteers and only reads what is shared with the Rangers. The two never mix, because a flock place is per-flock and the check asks about this flock every time.
How to verify it: open the Access inspector, pick Ana and a Rangers item, and confirm the refusal names her place in that flock. If it names something else, the setup is not what you think it is.
#6. A staff flock with extra powers: the Rangers
Volunteers log sightings. The Rangers do more — verify, unverify, keep the public map honest.
Set up
- Sam creates a role,
ranger, that may editstatus(no preset, no validation pinning it — recipe 3 put those onvolunteeronly). - Sam adds that role to the Rangers' catalogue — the set of roles that flock is allowed to hand out.
- The flock's admins assign it to the right members.
Why it is safe to let ordinary users run flocks. A flock admin can only assign roles from their flock's catalogue, and only an administrator can edit a catalogue. They pick from a menu they cannot extend, so a flock admin can never hand themselves — or anyone else — something Sam did not offer.
What this does not do
It does not let a flock place exceed the Nest role. Being an admin of the
Rangers conveys nothing outside the flock; the power to set status comes from
the ranger role, and only Sam decides which roles a flock's catalogue offers.
#7. Give the Coastal Volunteers a real capability, safely
Flock members should be able to correct species records — but Priya, who runs the flock, must never be able to hand out administrator access.
Set up
- Create a role
species_editorwith the permissions it needs. - Under Auth → Roles, turn on Flock-assignable for it. (Roles with administrator access cannot be marked — the toggle is disabled.)
- On the Coastal Volunteers' page, under Roles this flock can assign, press
Edit and tick
species_editor. - The flock's own admins — Priya — can now give it to members, from that list only.
What this does not do. It does not let Priya add anything else to that
list. Only somebody holding system/crews manage — a Nest administrator —
can change the catalogue.
Why the split. The person who chooses who gets a role must not also choose which roles exist. If they were the same person, a flock admin could put an admin role on their own menu and then take it — and anybody can create a flock.
#8. Let the flock correct species — but never re-home sightings
Priya wants the flock's editors fixing her species names and notes. She does not want her sightings moving into someone else's flock, or anyone else becoming their creator.
Set up
Share the season's sightings with the Coastal Volunteers at Edit. That is all.
Ana, an editor in the flock, can now fix species names and notes. And the second half is built in, not configured: a share lets you edit a record in place; it never lets you move it. The columns that say where a record lives — its flock, its creator — cannot be changed through a share, whatever level it carries.
What this does not do
It does not narrow editing down to only the species column. An Edit share lets
Ana change whatever fields her role may write. To pin a particular field shut —
status, say — put a must-stay rule (validation) on the role, exactly as
recipe 3 does for volunteers.
#9. Files that belong to the person who uploaded them
The image files behind the sightings — the photos container — should follow
the same rule as the records.
Set up: on system/files, give the role update and delete with a row scope
of Own. That is the shipped default for editor.
Then share. Priya shares a file with the flock, and members reach it at the level she chose, bounded by their place in the flock — the same rule as records.
What this does not do
It does not cover containers. A container is the upload target a whole team
routes files through, so it is administrator-level and has its own permission
(system/file-containers). Someone who may manage their own files is not
thereby allowed to re-point everyone's storage.
#10. Let one person see one sighting — without making a flock for them
What you want. "Ben knows this species better than I do. Let Ben see this one sighting, and nothing else of mine."
What to set. Nothing, in advance. Open the sighting and share it with Ben by name at View — or Edit if Ben should be able to fix the identification.
POST /api/v1/shares
{ "itemType": "record", "collection": "sightings", "itemId": "<id>",
"userId": "<ben>", "level": "view" }
What it does not do. It does not give Ben anything on Priya's other sightings, and it does not let Ben pass the record on — that needs Manage, and Priya keeps it as the owner.
You do not need a flock for this. Ben is in no flocks at all, and the share works anyway. Before shares could name a person, the only way to say "just Ben" was to create a flock containing Ben — which works, and leaves you with one flock per share and a flock list nobody can read. Make a flock when the audience is a group; share by name when it is a person.
#11. Lend something until a date
What you want. A visiting researcher needs this season's sightings until their survey is written up.
What to set. Share each sighting with them by name — or once with a flock
they are in — and set expiresAt.
POST /api/v1/shares
{ "itemType": "record", "collection": "sightings", "itemId": "<id>",
"userId": "<researcher>", "level": "view", "expiresAt": 1767225600 }
What it does not do. It does not delete anything when it lapses. The access stops on the date; the share row stays until somebody revokes it, and it is excluded from every count in the meantime — so the access inspector shows live access, not history.
Watch out. An expiry is not a substitute for a role. If the researcher's role can read every sighting in the collection anyway, expiry on one share changes nothing about the rest.
#12. Hide a nesting site everywhere
What you want. A sighting sits on a sensitive nesting site. It must vanish for everyone — the flock it is shared with, the public map, the Rangers, Sam — until the season ends. Deleting it is wrong: the record and its history must survive for the survey.
What to set. A never-rule. Give the
sightings collection a sensitive field (a boolean, default false), then:
POST /api/v1/restrictions
{
"resource": "collections/sightings",
"filter": { "sensitive": { "_eq": true } },
"reason": "Nesting sites withheld under the survey protocol"
}
Set once, this works for every future nesting site too: marking any sighting's
sensitive field true removes it from every list, search, share and rule, for
everybody — never-rules bind administrators by default. Clearing the field
brings the sighting back exactly as it was, shares and all.
What it does not do. It does not delete or alter the record, and it does not
touch the shares — they simply stop reaching the row, and resume if the mark is
cleared. And it does not tell anyone why a sighting vanished, which is exactly
why the reason is required: it is shown wherever the rule's effect is
reported.
Who can set it. Writing never-rules takes the system/roles manage
permission — the people who can hand out access are the people who can fence
it.
#Testing a setup before you rely on it
Three habits, in order of how often they catch something:
- Test the role that has a FILTERED permission, not the one with nothing. A viewer is refused everything, so a viewer test passes whether your rule works or not. The role that is partly allowed is the one that discriminates.
- Check the write, not only the read. Reading and writing are separate permissions and they can disagree.
- Use the Access inspector. It reports which rule produced the answer, which is faster than reasoning about it — and it will tell you when the reason is something you did not expect, including a never-rule you forgot was there.