Skip to content

Organizations

Organizations group the users of a customer and the documents that belong to them. The concepts: roles, membership, effective roles, claims, invitations and deletion.

A B2B app needs “administrator of this customer, and only of this one”. Realm roles are realm-wide, and a list of member ids on each document doesn’t say who belongs to a customer or what they may do there. Organizations are backd’s answer: groups of users, owned by backd like users are, that documents can belong to and that rules can ask about.

This page explains the pieces. The rest of the section puts them to work: build a B2B app, rules cookbook and what happens when…. For departments and delegation there is a second layer, team roles, with recipes and a worked example; membership hooks, company context and company email templates complete it. The endpoints are in the organizations API and the settings in realm.yaml and collection.yaml.

The model

erDiagram
    USER ||--o{ MEMBERSHIP : "has"
    ORGANIZATION ||--o{ MEMBERSHIP : "has"
    MEMBERSHIP }o--o{ TEAM : "belongs to"
    MEMBERSHIP {
        string[] roles "direct organization roles"
    }
    TEAM {
        string[] roles "roles every member inherits"
    }
    ORGANIZATION ||--o{ TEAM : "has"
    ORGANIZATION ||--o{ INVITATION : "offers"
    ORGANIZATION ||--o{ DOCUMENT : "owns, as _meta.org"
    ORGANIZATION {
        object claims "plan, seats... written by admins and functions"
    }
  • An organization has a name, a unique slug, a status (active, orphaned when nobody can manage it any more, deleted) and optional claims.
  • A membership says that a user belongs to an organization, with the roles they were given there.
  • A team is a group of members that carries organization roles.
  • A document belongs to one organization when its collection says so, recorded in _meta.org.

Everything lives in the realm’s system database. An organization exists in one realm, and users, memberships and documents never cross realms.

Realm roles and organization roles

Realm rolesOrganization roles
Declared inrealm.yaml roles:realm.yaml organizations.roles:
Meaningthe same in the whole realmonly inside one organization
Held byusers, given by administratorsmembers, given by the organization’s managers
Checked withhasRole(user, 'editor')hasOrgRole(document._meta.org, 'editor')
What they openthe admin API areasmanage: [org, members, roles, teams] inside the organization

The two never mix. An organization or a team can’t carry a realm role, so nobody becomes a realm administrator by joining the right team, and a realm role grants nothing inside an organization. Realm administrators act through the admin API, not by being members.

Who sets _meta.org

Only backd, and only when a document is created: the caller names the organization (?org= on the request, inOrg(id) in the client), backd checks they are a member, and the create rule runs after that. A client can’t write _meta, and PUT or PATCH with a different _meta.org answers 400 immutable_field. Moving a document to another organization is a realm administrator’s job.

Which collections belong to organizations is a decision of each collection:

organization:Creating a documentDocuments
requiredneeds ?org=all belong to one
optionalmay name onesome do
none (default)?org= is refusednone do

Effective roles

What a member may do in an organization is the union of three sources, resolved once per request and never cached, so a change applies at the next request:

  1. Direct roles, given to the member in that organization.
  2. Team roles, the roles of every team they belong to.
  3. Default roles, organizations.default_roles, held by every member without being granted.

The members list returns each effective role with where it came from (direct, default or the team’s name), and marks in overlap a role held more than one way. Rules see the effective roles only, never team names: hasOrgRole(org, 'editor').

Direct roles or teams?

Both can give the same role, and mixing them for the same purpose is a trap: a member with editor directly and through the “Editors” team keeps editor after being taken out of the team, so the removal looks done and isn’t. “Who can edit?” also becomes a question with two places to look.

  • Management roles directly (owner, admin): few people, each one a decision.
  • Access roles through teams (editor, viewer): many people, one place to look.
  • Small organizations may use direct roles only. That is fine, as long as it is one way.

Claims

Claims are facts about an organization that rules can read and members can’t write: plan, seats, features. Only realm administrators and functions set them, up to 1 KiB, so a rule can trust them. Profiles, addresses and anything the members edit belong in a collection of your own. See limiting by plan.

Invitations

People join by accepting an invitation, which a manager creates with the roles or teams it gives. Three bindings decide who may accept:

BindingUse it whenWho can accept
useryou know the person’s accountthat user only
emailyou know their address, not whether they have an accountthe signed-in user whose verified address matches
noneyou share a link in a chat or a QR codeanyone signed in who holds the link; single use by default, expires in at most 30 days, never gives a managing role
sequenceDiagram
    participant M as Manager's app
    participant B as backd
    participant P as Invitee
    M->>B: POST /_orgs/{org}/invitations { binding, roles, send }
    B-->>M: { id, token, link } (shown once; the token is stored hashed)
    B->>P: the org-invitation email, when send is true
    P->>B: sign in, then POST /_orgs/invitations/preview { token }
    B-->>P: { org, roles, teams }
    P->>B: POST /_orgs/invitations/accept { token }
    B-->>P: the membership

The link is shown only when the invitation is made. There is no hosted accept page: accepting needs a session, so your app reads the token from the link, asks the person to sign in and calls preview and accept.

Who can see a document

For a collection in organizations, a read goes through the caller’s memberships. Because the rules are applied inside the database query, a non-member doesn’t get a “forbidden” for another organization’s documents: they never see them, in lists, counts or by guessing ids.

flowchart TD
    A[Request for a document or a list] --> B{Signed in?}
    B -- no --> X[Rules decide: usually nothing is visible]
    B -- yes --> C[Load the caller's memberships, once]
    C --> D{Organization requires MFA
and the session has none?} D -- yes --> E[That organization doesn't count:
its documents are invisible] D -- no --> F[Is _meta.org one of the caller's organizations?] F -- no --> G[Not visible] F -- yes --> H{Does the read rule also hold?
roles, claims, fields of the document} H -- no --> G H -- yes --> I[Visible]

Deleting an organization and erasing a member

They are different operations with different consequences:

Delete an organizationErase a member
Triggered bya manager (with re-authentication) or a realm administratorthe user, or an administrator, under erasure
Accessends at once for everybodyends at once for that user
Documentseach collection’s on_org_delete: delete removes them, keep leaves them for administratorsstay with the organization, with the owner cleared, unless the collection says on_owner_delete.in_org: apply
The organizationkept as a deleted recordstays; becomes orphaned if the erased user was its last manager
Undoan administrator can reactivate it, without members; delete documents are goneno

The content of an organization is the organization’s, not its authors’: erasing a person doesn’t delete what their company works with.

Build a B2B app

A step-by-step recipe: declare organization roles, mark collections, write rules, create the organization at sign-up, invite people and switch between organizations.

Rules cookbook

Copy-ready access rules for organizations: members read, admins delete, roles named by the document, limits by plan and a second factor per organization.

Team roles

Roles held within one team of an organization: declare them, give them to members, and list who holds what. Separate from organization roles and from the roles teams carry.

What happens when…

The consequences of leaving, erasure, deletion, transfers and role changes in an organization, plus the limits and the errors to expect.

Membership hooks

Run an internal function when people join, leave or change roles in an organization: onboarding, offboarding and syncing roles, with events that carry a sequence number.

Company context

Make backd’s own emails and hosted pages look like each company’s: pass the organization, and an internal function supplies the branding as {{.App}}.

Company email templates

Let each company edit its own emails for the kinds you allow: a logic-less syntax, a sanitized HTML, required placeholders, previews and test sends.

Team access recipes

Departments with managers, delegation with dates, cover from another team, moving people between teams, membership hooks and MFA for sensitive roles.

Example: HR absences

A company’s absence module built with team roles: employees ask, department managers and delegates decide, HR sees everything. A tested realm.

Edit this page · Last updated 15 Oct 2026