Permissions
DRF permission classes for workspace and team access control.
Default Permission
All API endpoints require authentication by default:
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",)Workspace Permissions
Defined in backend/workspaces/permissions.py:
| Permission Class | Read | Write | Delete |
|---|---|---|---|
IsWorkspaceMember | Member | Member | Member |
IsWorkspaceOwnerOrAdmin | Owner/Admin | Owner/Admin | Owner/Admin |
IsWorkspaceMemberForReadOwnerOrAdminForWrite | Member | Owner/Admin | Owner/Admin |
CanManageWorkspaceMembership | Member | Owner/Admin | Owner/Admin |
Team Permissions
| Permission Class | Read | Write | Delete |
|---|---|---|---|
IsTeamMember | Member | Member | Member |
IsTeamOwnerOrAdmin | Owner/Admin | Owner/Admin | Owner/Admin |
IsTeamPrivilegedUser | Team or workspace owner/admin | Team or workspace owner/admin | Team or workspace owner/admin |
IsTeamMemberForReadTeamPrivilegedUserForWrite | Member | Owner/Admin | Owner/Admin |
CanManageTeamMembership | Member | Owner/Admin | Owner/Admin |
Document Access
Documents and knowledge bases don't use a permission class. Every documents endpoint resolves what a user may see or change through one module, documents/access.py:
| Function | Rule |
|---|---|
readable_knowledge_bases(user, workspace) | Knowledge bases the user created, ones shared with a team they're in, workspace-wide ones, and all of them for admins |
writable_knowledge_bases(user, workspace) | Knowledge bases the user created, ones a team they're in has write access to, and all of them for admins |
visible_documents(user, workspace) | Documents the user uploaded, or that sit in a knowledge base they can read, and all of them for admins |
can_change_document(user, document) | The uploader, or a workspace admin or owner |
can_manage_knowledge_base(user, kb) | The knowledge base's creator, or a workspace admin or owner |
Chats search only the knowledge bases the person asking can read.
Other Permissions
| Permission Class | Description |
|---|---|
IsModelOwner | User is the owner of the object, such as the workspace owner for deleting a workspace or transferring it |
Roles
Two roles are defined in backend/workspaces/roles.py:
ROLE_ADMIN = "admin"
ROLE_MEMBER = "member"Roles apply to both workspace memberships and team memberships. The workspace owner is a separate field on the workspace and always has admin rights.
| Owner | Admin | Member | |
|---|---|---|---|
| Use chats and documents | ✓ | ✓ | ✓ |
| Invite people, manage members and teams | ✓ | ✓ | |
| Change workspace settings, archive it | ✓ | ✓ | |
| Buy a plan for the workspace | ✓ | ✓ | |
| Delete the workspace, transfer ownership | ✓ |
Rights end with membership: someone removed from a workspace loses their team roles and their right to manage invitations there.
Usage in ViewSets
Workspace-scoped views check membership against the workspace in the URL before building their queryset:
class ChatSessionViewSet(ModelViewSet):
permission_classes = [IsAuthenticated]
def get_queryset(self):
workspace = get_object_or_404(Workspace, pk=self.kwargs["workspace_pk"])
if not IsWorkspaceMember().has_object_permission(self.request, self, workspace):
raise PermissionDenied(_("You do not have access to this workspace."))
return ChatSession.objects.filter(workspace=workspace).filter(
Q(user=self.request.user)
| Q(shares__shared_with_user=self.request.user)
| Q(is_public=True)
)Every workspace-scoped ViewSet:
- Checks authentication
- Checks membership of the workspace in the URL, and refuses with
403otherwise - Filters querysets to that workspace, and within it to what the user may see