Group-based permissions

Grant a permission to a group of people and manage who belongs in one place, using the built-in Group schema. Rules name the group; membership lives in a single Group document, so when the group changes the rules stay untouched.

When to use this

Reach for a group whenever more than one rule applies to the same set of people, or when that set changes over time — an editorial team, a set of admins, a batch of beta testers. Naming each person in each rule means editing every rule whenever someone joins or leaves; naming a group once means editing only the group document.

Membership is keyed on verified email. If you need it keyed on something else, see Membership beyond verified email.

Store a group document

A https://pagelove.org/Group item carries a name and one member per email address. Store it anywhere on the host — a conventional home is a /groups.html page:

<div itemscope itemtype="https://pagelove.org/Group">
  <meta itemprop="name" content="editors">
  <meta itemprop="member" content="alice@example.com">
  <meta itemprop="member" content="bob@example.com">
  <meta itemprop="member" content="carol@example.com">
</div>

A request whose verified email matches one of the member values is granted the group's name (editors) as an actor. Only verified emails match — the principal's email_verified claim must be true — and a Group with a blank name is ignored.

Name the group in a rule

Use the group's name as an AuthorizationRule actor, exactly as you would a single user. This rule lets the editors write anywhere under /blog/:

<div itemscope itemtype="https://pagelove.org/AuthorizationRule">
  <meta itemprop="actor" content="editors">
  <meta itemprop="resource" content="/blog/*">
  <meta itemprop="method" content="POST">
  <meta itemprop="method" content="PUT">
  <meta itemprop="method" content="DELETE">
  <meta itemprop="action" content="Allow">
</div>

A group actor sits at the same specificity tier as a role or a verified email — below an exact username, above * — so the usual patterns compose: a blanket * … Deny alongside a specific editors … Allow grants the group and no one else. See Conflict resolution for how overlapping rules settle.

Change membership without touching rules

Adding or removing a member is an edit to the Group document — append or delete a member:

<div itemscope itemtype="https://pagelove.org/Group">
  <meta itemprop="name" content="editors">
  <meta itemprop="member" content="alice@example.com">
  <meta itemprop="member" content="dave@example.com">
</div>

Every rule that names editors picks up the change on the next request — no rule is edited. The Group document is the single source of truth for who its members are.

Membership beyond verified email

The built-in Group matches on verified email only. When you need membership keyed on something else — internal user ids, a service principal, a directory lookup — keep that membership in your own documents and expand it with a schema @read resolver on AuthorizationRule's actor property: a placeholder actor (say group:editors) is replaced with the concrete members on read. The Schema reference covers @read resolvers; only the membership source changes, not the rule model.

See also