Skip to content

Users and roles

Role May
admin everything: users, API keys, settings, rule switches and bank rules, LAR profiles, core field maps, teaching documents and fixing where a value comes from, diagnostics, metering actions; also holds every other role’s rights
manager everything a specialist may, plus override findings, mark funded, seal, read metering and the audit log; escalations are emailed to managers and administrators
specialist create and assign loans, upload, reprocess, review (accept / escalate), approve and reject packages, stage boarding, stage and export wires
boarding_checker approve a staged boarding or wire that someone else staged, commit an approved boarding; read loans and evidence
auditor_readonly read every loan, finding, evidence packet and rule page; verify evidence chains; nothing else
api_service the role behind API-key tokens; rights come from the key’s scopes (status:read, intake:write, evidence:read)

Roles are assigned per user (POST /v1/users/{id}/roles replaces the set); a user may hold several, for example specialist and manager. A role change takes effect within one access-token lifetime, because it revokes the user’s refresh tokens.

Users & access: the user list with roles, status and invite actions.Users & access: the user list with roles, status and invite actions.
Users & access. Invite by email, assign the least roles that work, disable without deleting.

Users & access (administrators) lists every user with roles, status and last sign-in. Add a user either emails an invite link (valid 72 hours, single-use) so the person sets their own password, or creates the user with a password. Deactivate switches an account off and revokes every session; user rows are never deleted, because evidence and audit reference them. You cannot deactivate yourself or remove your own admin role. Reset MFA is the lost-authenticator path (below).

Enforced by the platform, not by procedure:

  • The person who stages a boarding cannot approve it, even an administrator.
  • The person who stages a wire cannot approve it.
  • Overriding a finding takes a manager or administrator, a reason code from review.reason_codes and a justification of at least review.justification_min_length characters.
  • Reviewing, approving, boarding, wires, funding and sealing need a signed-in person; API keys are refused.
  • Sealed loans are read-only for everyone.
  • Password: Argon2id hashed; minimum length from auth.password_min_length. Users change their own with POST /v1/auth/password.
  • Email link: a single-use link sent through your relay, valid for auth.otp_ttl_minutes.
  • Either method can be switched off (auth.login_password_enabled, auth.login_otp_enabled).
  • Access tokens are short-lived RS256 JWTs; refresh tokens rotate and are revocable, and reusing a rotated refresh token revokes all of that user’s sessions. Both live in the browser’s memory only: no cookies, no local storage.
  • auth.allowed_email_domains restricts which addresses can be invited or created.
  • Sign-in endpoints allow 10 attempts per minute per client address; everything else allows 300 requests per minute per user or key.

With auth.login_totp_enabled on, anyone who has confirmed an authenticator app must enter its current six-digit code at every password sign-in. Each person enrolls on their account page (click your name, then Set up authenticator): add the setup key to an authenticator app or password manager and confirm with a first code. A user without an authenticator still signs in normally, so turning the policy on never locks anyone out. Codes are single-use, with one 30-second step of clock tolerance. If someone loses their device, an administrator uses Reset MFA in Users & access (DELETE /v1/users/{id}/totp), which also signs them out everywhere; they sign in again and re-enroll. Every enrollment, confirmation, removal and failed code is in the auth trail.

The account page: profile, password and authenticator enrollment.The account page: profile, password and authenticator enrollment.
The account page, where each person enrolls their authenticator.

Register Bookend with your identity provider (Entra ID, Okta, ADFS or any OpenID Connect provider) as a confidential web client with the redirect URI https://<bookend-host>/oidc/callback. Then set auth.oidc_authority (the issuer URL), auth.oidc_client_id, auth.oidc_client_secret and auth.oidc_provider_name, and turn on auth.oidc_enabled. The sign-in page gains a Continue with button named after the provider.

The identity provider authenticates; Bookend authorizes. The email the provider returns must belong to an existing, active Bookend user (accounts are never created automatically), roles stay Bookend’s own, and the session is the same short-lived token pair as every other method. Deactivating a user in Bookend ends their access whatever their status at the provider.

Administrators issue keys in Users & access → API keys (or POST /v1/api-keys) with one or more scopes; the key (bk_<prefix>_<secret>) is shown once and stored hashed. A key is exchanged for an access token at POST /v1/auth/token and used like a user token against REST and /mcp, limited to its scopes. Keys can never act on findings, approvals, boarding or wires. Revoke with DELETE /v1/api-keys/{id}. Every issue, exchange and revocation is an auth_events row.

GET /v1/audit?source=auth (System → Audit → “Sign-ins & API”) lists sign-ins, failed attempts, email-link requests, token refreshes and revocations, API-key use and every MCP call with the tool, the caller and the outcome.