Administrator User Guide
Version 2 · Added sections for the 5-tier role model, the new Roles management page, Site Clients, My Account self-service, and bulk-delete/search-fix behavior from the 2026-09-06/07 deliveries.
QDBAuth Administrator User Guide
Audience: anyone with Super Admin or Admin role access to QDBAuth's own dashboard, who creates/manages accounts for the QDB ecosystem's sites (CMS, TD, QDB admin, migration tool, and others). Superseded 2026-09-06: "admin-role access" now means one of two tiers — see "Roles, at a glance" below. A Developer / Support Lead / User login only ever reaches the self-service My Account page, not this dashboard — see that section near the end.
Prerequisites: an existing Super Admin or scoped Admin account, and at least one site registered under Manage Sites if you plan to grant site access to new users.
Roles, at a glance (2026-09-06)
| Role | What they can do |
|---|---|
| Super Admin | Everything below, every site — the old "global admin." |
| Admin | Users, Create-user, Site Config, and Site Clients — restricted to their own granted site(s) only. Never Manage Sites, Groups, or Logs. |
| Developer, Support Lead, User | Nothing in this guide — redirected to My Account instead. |
A site can also define its own role names (see "Manage a site's roles" below) — e.g. TD's staff use Developer/Support/Dev Lead/Support Lead/Super Admin instead of the shared default list. Whatever role a site defines as admin-equivalent grants Super Admin-level dashboard access to an account using that role and that site.
Log in
Go to /login/ with no return_url — this is the direct path into
QDBAuth's own dashboard (as opposed to a consuming app redirecting here for
SSO). Email + password, then a TOTP code from your authenticator app. On
success, a Super Admin or Admin lands on /dashboard/; a Developer/Support
Lead/User lands on /dashboard/account/ (My Account) instead.
Create a single user
- Dashboard → Users → Create user.
- Fill in first name, last name, email, and a placeholder password (the new user will replace this themselves during signup verification).
- Check the Sites to grant box(es). The Role dropdown automatically switches to reflect whichever site is checked — its own custom list if it has one (e.g. TD's 5 roles), otherwise the shared default list (Super Admin, Admin, Developer, Support Lead, User) — live, no page reload. The pre-selected option is whichever role that site (or the default group) has flagged as its default.
- Submit. One verification email is sent per granted site (or one if no site was granted). Each email lets that person independently set their own password and scan a QR code for that specific site's authenticator entry — completing one site's setup does not affect the others.
New users are also auto-enrolled into an auto-created "Default" group (Dashboard → Groups) as of 2026-09-06 — this happens automatically, nothing to check on this form.
Bulk-create users from a file
- Dashboard → Users → Bulk user management → upload a
.csvor.xlsxwith header rowfirst_name, last_name, email, password, role, sites. sitesis semicolon-separated (e.g.CMS;QDB admin) and must match existingsite_namevalues exactly — unknown names are silently dropped.rolemust be valid for whichever site(s) that row grants (checked against that site's ownsite_roleslist, or the shared default list) — an invalid role falls back to that group's default rather than failing the whole row.- A sample CSV is downloadable from the same page as a starting template.
- Rows with missing required fields or an already-used email are skipped and listed as errors after upload — everything else in the file still gets created.
Search and bulk actions (Users / Manage Sites)
- Searching Users now matches the full "First Last" name together, not just each field separately (fixed 2026-09-06).
- Clearing either page's search box (the native × in the field, or deleting down to empty) automatically reloads the full list — it used to require clicking Search again with an empty box.
- Both pages have a select-all checkbox + Delete selected for removing several rows in one action, in addition to each row's own delete button.
Manage a site's roles (new, 2026-09-07)
Dashboard → Roles (/dashboard/site-roles/): pick a site (a Super Admin
can also edit the shared "Default roles" fallback used by any site with
none of its own) to see its current role list. From here:
- Add a role — name it, and optionally flag it
Default(pre-selected when creating an account for that site) and/orAdmin-equivalent(assigning this role to a staff user setsis_admin=1— irrelevant for Site Clients, who never reach this dashboard regardless of role). - Make default / Make admin-equivalent — moves that flag onto a different existing role (only one role per site can hold each flag).
- Remove a role.
A site with no roles of its own uses the shared default list automatically — you don't need to "set up" every site, only the ones that need their own vocabulary (like TD already does).
Manage Site Clients (new, 2026-09-07)
Dashboard → Site clients (/dashboard/site-clients/) — each site's own
end-customers, previously managed outside QDBAuth. A Super Admin sees every
site's clients; a scoped Admin sees only their own site(s)'.
- Create site client — pick the site (locks the Role dropdown to that site's role list, same live-refresh behavior as Create User), name, username, and password. Unlike a staff user, a client logs in with a username, not an email — there's no address to send a verification link to.
- After creating one, you're taken straight to its on-screen QR setup page — scan it with an authenticator app (or hand the device to the client) and enter the confirmation code right there, the same way a site-admin staff account is set up.
- From the list: toggle active/inactive, reset password, reset authenticator (regenerates the QR — reopen the setup page afterward to show the new code), or delete.
- A client only ever logs in through their own site's
return_url— they can never reach the QDBAuth dashboard itself, no matter their role.
Reset a user's password
- Dashboard → Users → edit icon on their row.
- If the account has per-site credentials, a site selector appears above the password field — pick which site's password you're resetting (each site has its own). Accounts without per-site credentials (legacy accounts) just show a single reset field, no site picker.
- Enter the new password and click Reset. The user gets an email confirming their password was changed (so they notice if it wasn't them).
Manage sites
Dashboard → Manage sites: add a site (site_name + site_url), toggle a
site active/inactive, or delete one (single or multi-select). site_url is
used to auto-match a consuming app's SSO return_url back to a site name,
and (for accounts with per-site credentials) to build each verification
email's destination link.
Deactivate / delete a user
Toggling a user inactive immediately revokes all of their refresh tokens (they can't silently keep using an already-issued token) and blocks future logins, without deleting their data. Deleting is permanent, cannot target your own logged-in account, and (as of 2026-09-06) also removes the account from any group it belonged to, so a deleted user's row doesn't linger in a group's member list.
My Account — self-service (Developer, Support Lead, User)
A Developer/Support Lead/User login lands on /dashboard/account/ instead
of the admin dashboard — no Users/Sites/Groups/Logs access at all, only:
- Change their own password (with a site picker if they hold per-site credentials for more than one site).
- Reset their own authenticator (emails a fresh setup link).
- Change or remove their own profile picture.
Activity log
Dashboard → Logs is split into two tabs (2026-09-06):
- Admin Events — user/site/group management, role and config changes.
- User Events — login, logout, failed login, and self-service password reset requests/completions.
Troubleshooting
"Table 'qdb.user_site_credentials' doesn't exist" when creating a user —
the per-site credentials database migration
(db/create_user_site_credentials_table.sql) hasn't been run against the live
database yet. Run it once; it's a single CREATE TABLE, safe to run anytime.
The same applies to db/create_site_clients_table.sql and
db/create_site_roles_table.sql before using those two newer features —
see Changelog.
A second/third site's verification link says "already verified" — this
was the original (fixed) behavior for accounts sharing one credential across
sites. If it still happens on a NEW account, check whether that account
actually has rows in user_site_credentials (new-style) — if it doesn't
(legacy), that's expected: legacy accounts intentionally share one credential.
A consuming app gets 401 on every call — check its
X-QDB-Client-Secret header value matches QDB_SSO_SHARED_SECRET exactly.
"Invalid email or password" for a real account — for new-style
(per-site) accounts, confirm the site value the consuming app sends matches
a registered site_name exactly; a mismatch falls through to the account's
siteless credential (if any), which won't match a site-specific password.
For a Site Client specifically, also confirm return_url was actually sent
— a client login with no resolvable site is always rejected.
Verification
After creating a test user: confirm the verification email(s) arrive, that
each one's QR code / password-set flow works end to end, and that the person
can subsequently log in through whichever consuming app(s) they were granted.
After creating a test Site Client: confirm the on-screen QR setup completes,
and that logging in via /login/?return_url=<their site's URL> redirects
back to that site with a token rather than landing on the QDBAuth dashboard.