Skip to main content
QFieldCloud uses a comprehensive role-based access control (RBAC) system to manage permissions at both the organization and project levels.

Permission Hierarchy

Permissions in QFieldCloud operate at three levels:
  1. Organization Level: Controls organization management and membership
  2. Project Level: Controls project access and operations
  3. Resource Level: Controls specific actions (files, deltas, jobs, etc.)
Organization roles and project roles are independent. An organization member can have different roles on different projects.

Organization Roles

Organization roles determine what users can do within an organization.

Organization Owner

The user who owns the organization (stored as organization_owner). Capabilities:
  • All admin permissions
  • Manage billing and subscriptions
  • Transfer ownership to another member
  • Delete the organization
  • Change subscription plans
  • Manage payment methods and storage packages
Cannot:
  • Be removed as a member (only ownership can be transferred)
  • Be added as a regular member
Role Origin: organization_owner

Admin Role

Organization administrators have extensive management permissions. Capabilities:
  • ✅ Add and remove organization members
  • ✅ Create and delete teams
  • ✅ Create organization-owned projects
  • ✅ Manage organization settings (profile, avatar, etc.)
  • ✅ Add/remove team members
  • ✅ Create and delete organization secrets
  • ✅ View all organization members
  • ✅ Assign project collaborators to organization projects
Cannot:
  • ❌ Manage billing and subscriptions
  • ❌ Delete the organization
  • ❌ Transfer organization ownership
Role Origin: organization_member with role admin Code Reference: qfieldcloud/core/models.py:774
class OrganizationMember:
    class Roles(models.TextChoices):
        ADMIN = "admin", _("Admin")
        MEMBER = "member", _("Member")

Member Role

Standard organization members with basic access. Capabilities:
  • ✅ View organization profile
  • ✅ View other organization members
  • ✅ Access projects where they’re added as collaborators
  • ✅ Be added to teams
  • ✅ View teams they belong to
Cannot:
  • ❌ Add or remove members
  • ❌ Create or delete teams
  • ❌ Create organization projects (can create personal projects)
  • ❌ Manage organization settings
  • ❌ Manage organization secrets
Role Origin: organization_member with role member

Project Roles

Project roles control access to specific projects and their resources.

Role Overview

RoleReadWrite FilesEdit DataDelete FilesManage SettingsManage Collaborators
Admin
Manager
Editor
Reporter✅ (create only)
Reader

Admin

Full project control with all permissions. Capabilities:
  • ✅ All Manager permissions
  • ✅ Create and delete project secrets
  • ✅ Delete unnecessary file versions
  • ✅ Full administrative access
Use Cases:
  • Project owners
  • Senior team leads
  • Users who need full control
Code Reference: qfieldcloud/core/models.py:1982
class ProjectCollaborator:
    class Roles(models.TextChoices):
        ADMIN = "admin", _("Admin")
        MANAGER = "manager", _("Manager")
        EDITOR = "editor", _("Editor")
        REPORTER = "reporter", _("Reporter")
        READER = "reader", _("Reader")

Manager

Project management capabilities without full admin rights. Capabilities:
  • ✅ View and retrieve project
  • ✅ Update project settings
  • ✅ Delete project
  • ✅ Upload and create files
  • ✅ Delete files
  • ✅ Create and read deltas (data changes)
  • ✅ Apply pending deltas
  • ✅ Set delta status
  • ✅ Read jobs
  • ✅ Add/remove collaborators
  • ✅ Update collaborator roles
  • ✅ Modify QGIS project files
  • ✅ Read packages
Cannot:
  • ❌ Manage project secrets (admin only)
  • ❌ Delete unnecessary file versions (admin only)
Use Cases:
  • Team leads
  • Project coordinators
  • Power users who manage day-to-day operations
Permission Functions: qfieldcloud/core/permissions_utils.py:279-298

Editor

Data editing permissions with file management. Capabilities:
  • ✅ View and retrieve project
  • ✅ Upload and create files
  • ✅ Delete files
  • ✅ Create and read deltas
  • ✅ Read jobs
  • ✅ Modify QGIS project files (if not restricted)
  • ✅ Read packages
Cannot:
  • ❌ Update project settings
  • ❌ Delete project
  • ❌ Manage collaborators
  • ❌ Apply or set delta status
  • ❌ Modify restricted project files
Use Cases:
  • Field workers
  • Data collectors
  • Users who edit and upload data
Permission Functions: qfieldcloud/core/permissions_utils.py:301-335

Reporter

Data collection role with limited editing. Capabilities:
  • ✅ View and retrieve project
  • ✅ Upload files
  • ✅ Create new features (deltas with method=Create)
  • ✅ Read deltas
  • ✅ Read jobs
  • ✅ Modify QGIS project files (if not restricted)
  • ✅ Read packages
Cannot:
  • ❌ Delete or edit existing data (except create new)
  • ❌ Delete files
  • ❌ Update project settings
  • ❌ Manage collaborators
Use Cases:
  • Survey participants
  • Data contributors
  • Users who only add new data
Special Behavior:
# From permissions_utils.py:448-467
def can_create_delta(user: QfcUser, delta: Delta) -> bool:
    project: Project = delta.project

    # Editors and above can do anything
    if user_has_project_roles(user, project, [
        ProjectCollaborator.Roles.ADMIN,
        ProjectCollaborator.Roles.MANAGER,
        ProjectCollaborator.Roles.EDITOR,
    ]):
        return True

    # Reporters can only CREATE new features
    if user_has_project_roles(user, project, [ProjectCollaborator.Roles.REPORTER]):
        if delta.method == Delta.Method.Create:
            return True

    return False

Reader

Read-only access to project data. Capabilities:
  • ✅ View and retrieve project
  • ✅ Read files
  • ✅ Download packages
Cannot:
  • ❌ Upload or create files
  • ❌ Edit or delete data
  • ❌ Create deltas
  • ❌ Update project settings
  • ❌ View jobs (requires Reporter or above)
Use Cases:
  • Stakeholders
  • Viewers
  • Users who only need to see the data
Permission Functions: qfieldcloud/core/permissions_utils.py:345-356

Role Origins

Users can have project access through different origins:

Project Owner

Automatic Admin role for project owner.
  • Origin: project_owner
  • Role: Admin
  • Cannot be removed as collaborator

Organization Owner

For projects owned by organizations, the organization owner gets automatic Admin role.
  • Origin: organization_owner
  • Role: Admin
  • Automatically granted

Organization Admin

Organization admins get Admin role on all organization projects.
  • Origin: organization_admin
  • Role: Admin
  • Automatically granted

Collaborator

Directly added to the project with a specific role.
  • Origin: collaborator
  • Role: Any (Admin, Manager, Editor, Reporter, Reader)
  • Explicitly assigned

Team Member

Member of a team that’s added as a collaborator.
  • Origin: team_member
  • Role: Inherited from team’s assigned role
  • Automatically granted when team is added

Public

For public projects, all authenticated users.
  • Origin: public
  • Role: Reader
  • Automatically granted
Code Reference: qfieldcloud/core/models.py:968
class ProjectQueryset:
    class RoleOrigins(models.TextChoices):
        PROJECTOWNER = "project_owner", _("Project owner")
        ORGANIZATIONOWNER = "organization_owner", _("Organization owner")
        ORGANIZATIONADMIN = "organization_admin", _("Organization admin")
        COLLABORATOR = "collaborator", _("Collaborator")
        TEAMMEMBER = "team_member", _("Team member")
        PUBLIC = "public", _("Public")

Permission Checks

The system provides helper functions to check permissions:

Organization Permissions

from qfieldcloud.core.permissions_utils import (
    can_create_members,
    can_read_members,
    can_update_members,
    can_delete_members,
    can_create_project,
    user_has_organization_roles
)
from qfieldcloud.core.models import OrganizationMember

# Check if user can add members
can_add = can_create_members(user, organization)

# Check if user is an admin
is_admin = user_has_organization_roles(
    user,
    organization,
    [OrganizationMember.Roles.ADMIN]
)

# Check if user can create projects in org
can_create = can_create_project(user, organization)
Code Reference: qfieldcloud/core/permissions_utils.py:130-156

Project Permissions

from qfieldcloud.core.permissions_utils import (
    can_retrieve_project,
    can_update_project,
    can_delete_project,
    can_create_files,
    can_delete_files,
    can_create_deltas,
    can_modify_qgis_projectfile,
    user_has_project_roles
)
from qfieldcloud.core.models import ProjectCollaborator

# Check if user can access project
can_access = can_retrieve_project(user, project)

# Check if user can upload files
can_upload = can_create_files(user, project)

# Check if user is manager or admin
is_manager = user_has_project_roles(
    user,
    project,
    [ProjectCollaborator.Roles.ADMIN, ProjectCollaborator.Roles.MANAGER]
)

# Check if user can modify QGIS project files
can_modify = can_modify_qgis_projectfile(user, project)
Code Reference: qfieldcloud/core/permissions_utils.py:264-427

Special Permission Cases

Restricted Project Files

Projects can enable has_restricted_projectfiles to limit QGIS project file modifications:
# When has_restricted_projectfiles is True:
# - Only Admin and Manager can modify .qgs, .qgz, .qgd files
# - Editors and Reporters cannot modify these files

def can_modify_qgis_projectfile(user: QfcUser, project: Project) -> bool:
    if project.has_restricted_projectfiles:
        return user_has_project_roles(
            user,
            project,
            [ProjectCollaborator.Roles.ADMIN, ProjectCollaborator.Roles.MANAGER],
        )
    else:
        return user_has_project_roles(
            user,
            project,
            [
                ProjectCollaborator.Roles.ADMIN,
                ProjectCollaborator.Roles.MANAGER,
                ProjectCollaborator.Roles.EDITOR,
                ProjectCollaborator.Roles.REPORTER,
            ],
        )
Code Reference: qfieldcloud/core/permissions_utils.py:314-334

Collaborator Limits

Private projects have collaborator limits based on the owner’s subscription:
  • max_premium_collaborators_per_private_project: Maximum collaborators allowed
  • -1 means unlimited collaborators
  • Only premium users can be added to private projects
  • Teams count separately and are always allowed
  • Public projects have no collaborator limits
Code Reference: qfieldcloud/core/permissions_utils.py:623-689

Incognito Collaborators

Collaborators can be marked as “incognito”:
class ProjectCollaborator(models.Model):
    is_incognito = models.BooleanField(
        default=False,
        help_text=_("If a collaborator is marked as incognito, they will work as normal, "
                    "but will not be listed in the UI or accounted in the subscription as active users.")
    )
  • Work normally with full permissions
  • Not listed in UI
  • Not counted in billing/active user metrics
  • Used for support staff access
Code Reference: qfieldcloud/core/models.py:2014-2019

API Examples

Check User’s Project Role

import requests

# Get project details (includes user's role)
url = f"https://app.qfield.cloud/api/v1/projects/{owner}/{project_name}/"
headers = {"Authorization": "Token YOUR_API_TOKEN"}

response = requests.get(url, headers=headers)
project = response.json()

print(f"Your role: {project['user_role']}")
print(f"Role origin: {project['user_role_origin']}")

Add Collaborator with Role

import requests

url = f"https://app.qfield.cloud/api/v1/projects/{owner}/{project_name}/collaborators/"
headers = {
    "Authorization": "Token YOUR_API_TOKEN",
    "Content-Type": "application/json"
}
data = {
    "collaborator": "username",
    "role": "editor"  # or admin, manager, reporter, reader
}

response = requests.post(url, json=data, headers=headers)
collaborator = response.json()
print(f"Added {collaborator['collaborator']} as {collaborator['role']}")

Update Collaborator Role

import requests

url = f"https://app.qfield.cloud/api/v1/projects/{owner}/{project_name}/collaborators/{username}/"
headers = {
    "Authorization": "Token YOUR_API_TOKEN",
    "Content-Type": "application/json"
}
data = {"role": "manager"}  # Promote to manager

response = requests.patch(url, json=data, headers=headers)
updated = response.json()
print(f"Updated to {updated['role']}")

Best Practices

Assign the minimum role needed for users to perform their tasks. Start with Reader or Reporter and elevate only when necessary.
Instead of adding many individual collaborators, create teams and assign role to the team. This simplifies management.
Only grant Admin role to users who need full control. Use Manager for day-to-day operations.
Field workers who only add new observations should be Reporters, not Editors, to prevent accidental data modification.
For production projects, enable has_restricted_projectfiles to prevent accidental modification of QGIS project configuration.
Track collaborator count against plan limits for private projects to avoid disruption.

Permission Matrix

Organization Permissions

ActionOwnerAdminMember
View organization
Update settings
Manage billing
Add/remove members
Create teams
Create projects
Delete organization
Transfer ownership
Manage secrets

Project Permissions

ActionAdminManagerEditorReporterReader
View project
Update settings
Delete project
Upload files
Delete files
Read files
Create features
Edit features
Delete features
Apply deltas
Manage collaborators
Manage secrets
View jobs

Organizations

Learn about organization management

Members

Manage organization members and teams

Build docs developers (and LLMs) love