Roles and claims

Every person has one role, stored on their users record and copied onto their sign-in account as a custom claim. The security rules and the Cloud Functions read the claim, and only an admin or the server can change it.

The roles

RoleWhoWhat they can reach
(signed out)VisitorsThe public site: published content, tags, media, the public settings, signup forms.
userEveryone who signs up, unless the site sets another defaultThe member area; their own users record, except the fields listed below; reading their own storage folder and uploading their profile photo; whatever your app's rules grant on their own data.
editorContent staffWriting content types, content and drafts, tags, media and the publish queue, and uploading files. Nothing in the admin area grants this role, and every admin page is for admins only, so in practice content staff are admins.
adminThe people who run the siteEverything: the admin area, every users record, the settings, the admin callables and the whole storage bucket.

Where each role lands after signing in (admins on /admin/dashboard, everyone else on /user/dashboard) is set in src/custom/home.ts: see Build the member area.

The two claims

ClaimHoldsRead by
arccms_roleThe role from the users recordisAdmin() and isEditor() in the rules; isArcAdmin() and requireAdmin() in the functions
arccms_uidThe id of the person's users record, which is not their Auth uidownsUserRecord(userDocId) in the rules; your app, from the ID token

Arc CMS never reads or writes a plain role claim, and always merges its claims into the account's existing ones. So an app sharing the sign-in pool can use role for its own roles without giving anyone Arc CMS access, and claims it sets survive. Claims writes on one account take turns: each holds a short lease while it reads, writes and reads back, so Arc CMS's claims and an app's keep each other when both go through Arc CMS (an app sets its own with mergeAppClaims(); App accounts says exactly what is guaranteed). Do not name an app claim arccms_ anything. How an app reads the claims is in Follow the account contract.

How a role is granted and changed

Whenever a record is created or its role changes, the onUserRoleChange function copies the role and the record id onto the account as claims. A blocked record gets no claims, and its sessions are ended. The admin screens are described in Users and roles.

At every sign-in the browser compares the token's claims with the record and, when they differ, asks the server to set them again (refreshMyClaims) before it lets the person in. Someone already signed in gets a new role when their ID token refreshes, within the hour, or at their next sign-in. An admin can re-apply every account's claims with the syncAllUserRoles callable.

Why nobody can promote themselves

  1. The rules. Only admins create users records from the browser; every sign-up creates its record on the server. A person may update their own record, but never role, uid, the block switches (isActive, status), their email or phone, or the premium fields, and emailVerified may only go to false. Settings/users, which holds the default role for sign-ups, is admin write only.

  2. The role trigger. If a role other than user is ever written by someone who is not an admin (by the claim) and not the server, onUserRoleChange refuses it, logs an error and puts the old role back. The claim does not follow. The server here means a write the database reports as a service account or the system, or one made by this project's own service accounts (such as <project-number>-compute@developer.gserviceaccount.com, which 2nd gen functions run as). Another project's service account is not trusted.

  3. The first admin, once. claimFirstAdmin checks, in one transaction, that no admin has ever been made, and leaves a marker that no browser can read or write.

The browser's route guards (src/app/guards/role.guard.ts) read the role from the record (the device's copy when the offline cache has one, then the server's: What the guards wait for), but they only decide which pages show. The rules and the functions decide what data anyone can touch. See Security rules.