In one sentence
The Users admin page is where every person in your organization is provisioned, role-assigned, seat-assigned, and password-managed — with two ways to add new people (email invite or temp-password handoff) and a per-user permission grant if you need to give a single individual a capability without changing their role.
- Two add-user paths. Invite by email sends a magic link and the user sets their own password. Create with temp password skips email entirely — the admin gets the temp password back once and shares it out-of-band. Pick the path that matches your security posture.
- Three layers of capability. Base role (Admin / Standard User) is the floor. Additional roles layer on extra permissions. Per-user permission grants are the surgical tool for "give this one person this one thing" without inventing a new role.
- Seats are a billing concept. Each member has a seat type (Full, Approver, R&A). Seats are billed; downgrading is free, upgrading enforces your plan's cap.
The Users page
Admin → Users. Admin-only.
The page lists every active member with their base role, additional roles, seat type, and inline actions. Search by name or email.
Each row carries quick affordances:
- Base role dropdown — change Admin / Standard User in place.
- Seat type dropdown — change Full / Approver / Read & Acknowledge.
- Additional roles chips — add or remove custom roles inline.
- Reset password — generate a one-time temp password and force a change on next sign-in.
- Manage permissions — open the per-user permission grants panel.
Adding a new user
Two paths, both behind the Add user button.
Path 1 — Invite by email
Sends a magic-link email through Supabase's invite flow. The user clicks the link, sets their own password, and lands authenticated.
Use this when:
- The user has a working email address you trust.
- Your auth policy allows password sign-in (or you've already wired up SSO for their domain).
- The user's email domain matches your org's Allowed email domains policy if one is set — otherwise the invite is rejected up-front with a clear error.
The pre-filled fields on the invite form become the user's profile state immediately: full name, base role, seat type, optional additional roles, facility scope. They don't have to set those themselves — they pick a password and they're in.
Path 2 — Create with temp password
Skips email entirely. The admin types the user's details, the system generates a temp password, and the dialog shows that password once. The admin shares it out-of-band (in person, on paper, in a different secure channel).
Use this when:
- Email isn't trusted or isn't available (manufacturing-floor workstations, contractors with no corporate mailbox).
- Your org's policy is to never send credentials over email.
- You need to onboard a batch of users right now and can hand them their first-time password directly.
The user's must_change_password flag is set so their first sign-in forces a password change immediately. The original temp password becomes useless after that one sign-in.
The temp password is shown exactly once. There's no way to retrieve it later. If you close the dialog before sharing the password, run Reset password on the user to generate a new one.
Base role vs additional roles vs per-user permissions
QFormance has three layers for granting capability — pick the layer that matches the scope of the grant.
Base role
Every user has one — Admin or Standard User.
- Admin has every permission and bypasses training gates. Use sparingly.
- Standard User has the minimum —
moc.createandexemption.createonly by default (customizable). Everything else comes from the layers below.
The base role is in the row's dropdown. Changing it is logged to Auth activity as a Role changed event with from/to values.
The system refuses to demote the last remaining Admin in the org. Without this guard, an admin could lock the entire organization out of admin-gated settings. If you genuinely need to swap admins, promote the new admin first, then demote the old one.
Additional roles
Custom roles you've created (Quality Manager, Lead Auditor, Document Reviewer, etc.) layered onto a user on top of their base role. A user can hold any number.
Manage additional roles inline on the row — pick a role from the Add role picker, or click ✕ on a chip to remove. See Roles & permissions for how custom roles are built.
Per-user permission grants
Sometimes you want one person to have one capability without creating a whole role for it. The Manage permissions action opens a panel listing every catalog permission with the user's current effective state.
- Permissions that the user gets from their base or additional roles are shown as granted by role (locked — you can't subtract from a role's permissions on a single user).
- You can directly grant any extra permission, layering it on top of role-derived ones.
- You can revoke a previously-granted direct permission.
Use direct grants sparingly — they're harder to audit than roles. The right answer is usually to create or extend a custom role; the per-user grant exists for the cases where that's overkill.
Seat types
Three seat types, each with different capability and price:
| Seat type | What they can do | Notes |
|---|---|---|
| Full | Everything their role permissions allow — author, approve, investigate | Standard licensable seat |
| Approver | Read documents, approve in their queue, no authoring | Lower-cost seat for executives / reviewers |
| Read & Acknowledge (R&A) | Read distributed documents, acknowledge them, use Ask the Library — nothing else | See Read-and-Acknowledge users |
Seat type lives in its own dropdown on each user row.
Downgrading (Full → Approver, Approver → R&A) is always free and immediate.
Upgrading (R&A → Approver, Approver → Full) enforces your plan's seat cap. A Starter org capped at 10 Full seats can't move an 11th R&A user to Full — the action errors with a clear message about what's available. Either deprovision an existing Full user or upgrade your plan first.
Every seat-type change re-syncs your Stripe subscription so the cost line items match within seconds. See Billing & seat overages for the cost mechanics.
Resetting a password
Click Reset password on a user row. A confirmation dialog opens. Confirm, and the system generates a new temp password, sets must_change_password = true, and shows you the password once.
Share the new password out-of-band the same way you would for Create with temp password. The user signs in once with it, immediately gets prompted to set a real password.
This is the right flow for:
- A user who's lost their device and can't recover via passkey or normal password reset.
- A user whose account you suspect is compromised — reset and force a change.
- A user who never signed in after their original invite expired.
Reset events land in Auth activity as Password reset with the target name.
What this page doesn't do
- There's no deactivate or remove-from-org action. A user added to your org stays until they're explicitly removed via support / database action. To prevent someone from signing in, reset their password and don't share the new one; they'll be locked out. (A proper deactivate flow may be added; if you need it, raise it with your account contact.)
- It doesn't manage SSO directly. SSO sign-in is configured at Admin → Organization → Auth Policy; this page just creates the user record. An SSO user signs in via their identity provider; this page is irrelevant to their first sign-in if you're SSO-only.
- It doesn't grant cross-org access. Users belong to exactly one organization. There's no concept of an external collaborator with multi-org membership in the customer-facing product today.
Related
- Roles & permissions — how the role system works
- Read-and-acknowledge users — the R&A seat type in detail
- Auth & sign-in policy — sign-in methods, domain restriction, step-up
- Auth activity — where role changes and password resets are surfaced
- Billing & seat overages — how seat costs are calculated
- Pricing & seat model