Permissions¶
Part of the user manual. Related: VISIBILITY · TENANCY · NOTIFICATIONS · ROLES · PROJECTS · WORKFLOWS.
Permissions = what you're allowed to do. CRUD (Create, Retrieve, Update, Delete) on a class of records, plus a narrower per-instance gate ("you can edit X in general, but to edit THIS specific X you also need to be the owner / project admin").
This page does NOT cover which records appear in your view — that's filtering, not permissions. If you're trying to answer "why can't user X see record Y?", start at VISIBILITY. The distinction matters: a user with full CRUD permissions on workflow events can still see zero events because every visibility layer filtered them out, and a user with no edit permission can still SEE plenty of records — they just can't change them.
TL;DR¶
- REBIM uses Django's per-model permission system:
add_X,view_X,change_X,delete_Xfor every model class. - Permissions are usually assigned via groups, not directly to
users. A handful of standard groups ship via the
seed_groupsmanagement command — see Default groups. - On top of Django's model permissions, per-instance gates apply for most edit / delete operations (owner / project admin / role rules). Both must pass.
- The Django admin panel is for SaaS superusers only. Tenant users never get a superuser login.
- Tenancy itself is a visibility concept, not a permissions one — brief pointer below, full coverage in TENANCY.
Two layers — model permissions and instance gates¶
Every action you take in REBIM is gated by two independent checks:
-
Model permissions (Django's per-model perms). "Can this user perform action X on records of type T at all?" Stored on
auth.Userdirectly, or — more usually — granted via group membership. The backend (REST API + views) checks them on every request. -
Instance gates (application-level rules). "Given the user has the model permission, is THIS specific record one they're allowed to act on?" E.g. "you have
change_project, but to edit THIS project you also need to be its owner or a project admin." See the per-module gates below for the specifics.
Both must pass. Lack the model permission and the API rejects before the instance gate ever runs. Have the model permission but fail the instance gate and the API still rejects.
The frontend respects these — buttons hide when the user can't act — but it's a UX courtesy, not the enforcement. The backend is authoritative.
Users¶
Permissions can be assigned to individual users (Django admin → Users → Permissions). In practice this is rarely the right tool:
- Hard to audit ("who can edit projects?" requires walking every user).
- Easy to drift ("this user got a one-off permission last year, why?").
- Hard to maintain ("new permission added — must update N user records").
Prefer groups for almost all real cases. Direct per-user permissions are for genuine exceptions only.
Groups¶
A group is a named bundle of model permissions assigned to multiple users. Standard practice across the codebase. Examples:
- Project Manager — can create / edit / delete projects.
- Document Controller — can create / edit / delete documents + data sources.
- Tenant Administrator — broader edit rights across configuration models.
To assign a user to a group: Django admin → Users → (pick user) → Groups → check the group(s).
To create a new group: Django admin → Auth → Groups → Add. Pick the permissions, save. Group definitions are tenant-agnostic — a group exists across the install; visibility of records the group's permissions apply to is then filtered by tenancy per user.
Default groups (seed_groups)¶
The seed_groups management command creates a standard set of groups
on a fresh install. Run once:
python manage.py seed_groups
Default group definitions:
- READ PERMISSIONS — baseline group for any active user:
| App | Action | Models |
|---|---|---|
| CORE | VIEW | Custom Field, Data History, Data Share, Data Tag, Email Template, Saved Layout, Tenant |
| DIRECTORY | VIEW | Company, Contact, Contact Type, Industry |
| EDMS | VIEW | Conversion, Conversion Request, Data Source, Document, Classification, Revision, Sequence, Status, Type |
| EDMS | ADD | Conversion Request |
| LIVEFEED | VIEW | Feed, Notification |
| LIVEFEED | ADD / EDIT / DELETE | Notification |
| PROJECTS | VIEW | Project, Role (discipline), Level, People, System |
| WORKFLOW | VIEW | Distribution Group, Event, Status, Transition, Transmittal, Transmittal Action, Transmittal Bake, Workflow |
| SCHEDULE | VIEW | Scheduled Events |
- WRITE PERMISSIONS — for users who edit data records (not configuration):
| App | Action | Models |
|---|---|---|
| DIRECTORY | ADD / EDIT / DELETE | Company, Contact |
| EDMS | ADD / EDIT / DELETE | Document, Document Revision |
| PROJECTS | ADD / EDIT / DELETE | People |
| WORKFLOW | ADD / EDIT / DELETE | Event, Transmittal, Transmittal Bake, Status, Transition, Workflow |
- PROJECTS CRUD — for users who manage project-level setup:
| App | Action | Models |
|---|---|---|
| PROJECTS | ADD / EDIT / DELETE | Project |
| EDMS | ADD / EDIT / DELETE | Data Source |
| SCHEDULE | ADD / EDIT / DELETE | Scheduled Events |
- TENANT ADMINISTRATOR — for users who manage tenant-wide configuration objects:
| App | Action | Models |
|---|---|---|
| CORE | ADD / EDIT / DELETE | Custom Field |
| EDMS | ADD / EDIT / DELETE | Data Source, Classification, Sequence, Status, Document Type |
| PROJECTS | ADD / EDIT / DELETE | Role (discipline), Level, System |
| WORKFLOW | ADD / EDIT / DELETE | Distribution Group, Status, Transition, Transmittal Action, Workflow |
A typical user is in READ PERMISSIONS plus one of the write-style groups depending on their job. Multiple write groups are valid (e.g. PROJECTS CRUD + TENANT ADMINISTRATOR for a power user).
Staff and the admin panel¶
The Django admin panel (at /admin/) is gated by Django's
is_superuser flag, NOT by group permissions or tenancy. Only the
SaaS administrator should have is_superuser.
Tenant users — even senior admins within a tenant — should never have a superuser login. Tenant-side administration of REBIM happens through the application's own admin surfaces (Project Admin role, Tenant Administrator group, etc.), not the Django admin panel.
Why this matters:
- The admin panel bypasses tenancy filters. A superuser sees every record in every tenant.
- The admin panel exposes models that the application UI deliberately hides (DataHistory, raw QueuedEmail records, etc.).
- A compromised superuser account is far worse than a compromised tenant-admin account.
If a tenant user needs an administration action you don't have a UI for, prefer adding it to the UI over granting them admin access.
Tenants — brief¶
Tenancy is REBIM's multi-tenant data model. Every record belongs to zero, one, or many tenants; every user belongs to zero, one, or many tenants; visibility is the intersection.
Tenancy is not really a permissions concept — it's a visibility filter. A user with full edit permissions on documents can still see zero documents because tenancy filtered them all out. For the full treatment see TENANCY.
For permissions purposes, two things matter here:
- Group permissions are tenant-agnostic. A user in the Document Controller group has edit rights on documents in every tenant they can see — tenancy only narrows which documents they see, not whether they can edit the ones they do see.
- "No tenancy" is itself a tenancy. A user with no tenants set sees only records that also have no tenants. This is occasionally a footgun on fresh installs — see TENANCY § No-tenancy is itself a tenancy.
Per-module edit / delete gates¶
For each module, this lists what's needed to edit or delete a specific record beyond the model permission. Read visibility — which records appear in the user's view at all — is covered in VISIBILITY.
Projects¶
Create: group permission (e.g. PROJECTS CRUD). No instance gate (it's a creation, no existing instance to gate against).
Edit / Delete: group permission AND the user is either:
- the project's owner (creator), OR
- a project admin (their ProjectPeople row in this project has
project_admin=True).
A user with the group permission but neither ownership nor project admin status on a given project cannot edit / delete that project, even though they can see it.
Contacts¶
Create / Edit / Delete: group permission (e.g. WRITE
PERMISSIONS) AND ONE of:
- the user is acting from a project where they hold project admin
status (or own the project), OR
- the user is the contact's owner (DirectoryContact.owner = user).
Useful when you assign an owner specifically so they can edit on
the frontend without being a project admin.
Note: the contact's email field, when set, overrides the
linked user's email for notification delivery — see CONTACTS § The
email caveat for the resolution rules
and edge cases (contacts without a site_login, deactivated users,
admin-CC paths that don't carry a contact).
Project People (membership)¶
Create / Edit / Delete: group permission AND the user is the project's owner OR a project admin OR a superuser.
Two flags on each ProjectPeople row affect what the assigned
person can do, not what the editor can do:
project_admin— grants the assignee in-project admin rights (manage other members, edit project settings).role_leader— grants the assignee broader visibility within their assigned disciplines (covered in ROLES, planned — for now see VISIBILITY § layer 4).
Disciplines (what would be called "roles" in many systems) are the
M2M on ProjectPeople.disciplines. Adding / removing disciplines on
a project person follows the same edit-gate rules above.
EDMS Documents¶
Create: group permission. Standard.
Edit: group permission AND: - the document is NOT checked out by another user (see Check-out below), AND - the document does NOT have an active workflow that locks editing (when an event references the document, edit may be restricted until the workflow completes).
Delete: group permission AND (typically) owner / project admin.
Check-out and locks¶
Documents can be checked out by a user, locking write actions to that user until they check it back in. While checked out:
- Editing the document is locked to the checked-out user.
- Editing workflow events that reference the document is locked.
- Workflow transitions on those events are locked.
- Tools (markup editor, etc.) open in view-only mode for other users.
- The Explorer respects the lock (can't add / transition / edit via Explorer either).
Project admins and superusers can override check-out locks for recovery cases (departed user, abandoned check-out).
Check-out is a state-specific rule that also affects VISIBILITY layer 5 — checked-out documents are still visible but most write actions are gated.
Workflow events¶
Create: group permission. Standard.
Edit: group permission AND ONE of: - the user is the event's owner (creator), OR - the user is the event's assignee, OR - the user is a project admin in the event's project, OR - the user is a superuser.
Transition (advance the event through its workflow): group permission AND the user holds a discipline that the next transition requires. Role mechanics live in ROLES; for now see VISIBILITY § layer 4.
Delete: group permission AND owner / project admin / superuser.
Workflow transmittals¶
Create: group permission. The user becomes the transmittal owner.
Re-transmit (send again): the user is one of: - the original transmittal creator, OR - a project admin in the transmittal's project, OR - a superuser.
Discussion / chat on a transmittal: any user who can see the transmittal can participate. Read-only access does not preclude discussion (this is intentional — discussion is the consultation channel).
Schedule¶
Create / Edit / Delete: group permission (SCHEDULE add/change/delete) AND project admin / superuser.
Note: being a project admin alone is not sufficient — they still need the SCHEDULE CRUD group permission. The instance gate adds to the group permission, doesn't replace it.
Read visibility — pointer¶
Read visibility (who sees which records) is covered in detail in VISIBILITY. The summary:
| Record type | Read visibility filtered by |
|---|---|
| Projects | Tenancy + project membership |
| Contacts | Tenancy |
| Documents | Tenancy + project access + data source tenancy + check-out for actions |
| Workflow events | Tenancy + project access + role rules + state-specific rules |
| Workflow transmittals | Tenancy + project access |
| Schedule events | Tenancy + project access |
| Configuration (workflows, statuses, etc.) | Tenancy |
If a user says "I can't see X," the answer is almost always in VISIBILITY, not here.
For developers¶
This page is for users and admins. Implementation pointers:
- Django permission classes:
core.views.BimPermissions(extendsDjangoModelPermissions) — applied to most viewsets. - Project-level instance gates:
core.utils.is_user_in_project,apps.projects.models.ProjectManager.for_user. - Workflow event instance gates: mostly client-side in
apps_workflow.js: can_user_perform_transition,is_owner_or_assignee. The backend may be more permissive than the frontend renders. - Check-out state:
EdmsDocument.checked_out_by. seed_groupsmanagement command:core/management/commands/seed_groups.py.
See devdocs/ for codebase-level material.