Roles & permissions
How Triconvey controls who in your firm can see and do what — built-in roles, custom roles, and per-key overrides.
The model in 30 seconds
Every action that touches data is gated by a permission key (e.g. can_create_file_matters). Each user has a role for the active business; the role grants a set of keys, and the server checks those keys on every request.
The frontend mirrors the same key set so the sidebar / buttons / pages can hide options the user can't actually use — but the backend is the source of truth. Hiding a button doesn't protect the data; the resolver / controller guard does.
Built-in roles
Five roles ship by default. The first user to sign up under a business automatically becomes the Business Owner.
- Business Owner — singleton per firm. Has every permission and bypasses permission checks server-side. Can't be deleted; ownership transfers manually.
- Business Administrator — full operational access. Manage team, billing, integrations, templates, settings. Can't delete the business itself.
- Lawyer — full conveyance toolset (file matters, documents, LTSA, LOTR, templates, contacts). Can't manage team or billing.
- Assistant — execute conveyance tasks but can't reassign work or change settings. Read most things, write within file matters.
- Viewer — read-only across the app. Useful for articling students or external auditors.
Custom roles
Firms can define their own roles when the built-ins don't fit — e.g. an Office Manager who needs to view team data and run reports but not touch file matter substance.
From Settings → Permissions, click + New role, name it, and tick the permission keys you want. The server starts honoring it immediately — no deploy needed. Existing built-in roles can't be edited (they're the safety net), only custom roles.
Model B — per-user overrides
Sometimes you need to grant a single permission to one person without changing their whole role. Example: an Assistant who also needs to approve trust transactions for a temporary stretch.
Triconvey supports this via per-membership permission overrides. The effective permission set for a request is computed as:
effective = role.permissions ∪ membership.granted_overrides \ membership.revoked_overridesOverrides are surfaced and edited per team member at Settings → Permissions → (member) → Custom permissions.
Permission categories
Keys are grouped so the editor stays scannable. The current categories — driven by the registry, so they evolve with the product:
- File Matters · Contacts · Documents
- Templates · Trust Accounting · Title Insurance
- Team · Permissions · Roles
- Business Settings · Billing · Integrations
- LTSA Web Filing · LOTR · LTSA Title Search
How a request gets authorized
- JWT validates → user identity + active business uid.
- Active membership lookup → user's role + per-membership overrides for this business.
- Endpoint declares
@RequirePermissions("...")→ guard checks the effective set. - If the key is missing → 403 Forbidden, with the missing key in the response so the frontend can decide what to render.
Heads-up: the Business Owner bypasses permission checks server-side (they always see everything), so the keys mostly matter for non-owner roles.