Skip to content

Manuals App — Permissions

This document describes the permission model for the Manuals app.


Overview

The Manuals app uses a capability-based permission system built on top of:

  • org membership roles
  • capability resolution (core.permissions.orgs)
  • DRF permission classes (manuals.permissions)

Permissions are enforced at the view layer and always scoped to the current organization.


Base requirements

All endpoints require:

  • IsAuthenticated
  • HasCurrentOrg

This ensures:

  • user is logged in
  • an active org is selected
  • all access is org-scoped

Capability model

Manuals introduce domain-specific capabilities:

  • view_manuals
  • manage_manuals
  • export_manuals
  • download_manual_files

These are resolved via:

  • org role → capabilities mapping
  • has_org_capability(...)

Role → capability mapping

Role View Manage Export Download
Owner V V V V
Admin V V V V
Manager V V V V
Engineer V X V V
Viewer V X V V

DRF permission classes

Located in:

manuals/permissions.py

CanViewManuals

Allows read access to manuals.

Used for:

  • list / retrieve endpoints
  • read-only access to related content

CanManageManuals

Allows write access to manuals and related content.

Used for:

  • create / update / delete
  • nested content changes
  • media upload
  • cover upload/remove

CanExportManuals

Allows exporting manuals (PDF).

Used for:

  • GET /manuals/{id}/export/pdf/

CanDownloadManualFiles

Allows downloading files.

Used for:

  • manual cover download
  • media download endpoints

View-level usage

ManualViewSet

Action Permission
list / retrieve CanViewManuals
create / update / delete CanManageManuals
export_pdf CanExportManuals
cover upload/remove CanManageManuals

ChapterViewSet / MediaViewSet / others

Action Permission
GET CanViewManuals
POST / PATCH / DELETE CanManageManuals

Download endpoints

Endpoint Permission
manual cover download CanDownloadManualFiles
manual media download CanDownloadManualFiles

Org scoping

All permission checks are combined with org filtering:

  • Manual.org
  • Chapter.manual.org
  • Section.chapter.manual.org
  • StepGroup.chapter.manual.org
  • Step.step_group.chapter.manual.org

This ensures:

  • users cannot access resources outside their org
  • even if they guess IDs

Design principles

1. Separation of concerns

Permissions are split by intent:

  • view vs manage vs export vs download

This avoids overloading a single permission.


2. Capability-based (not role-based)

Views do not check roles directly.

Instead they use:

has_org_capability(user=user, org=org, capability="...")

This allows:

  • flexible role changes
  • future feature flags
  • per-org customization (if needed later)

3. Consistency across endpoints

All Manuals endpoints follow the same pattern:

  • read → CanViewManuals
  • write → CanManageManuals
  • export → CanExportManuals
  • download → CanDownloadManualFiles

Future extensions

Potential future improvements:

  • restrict export to privileged roles only
  • restrict file downloads (e.g. external users)
  • introduce per-manual permissions (ownership / visibility)
  • add audit-based permission checks (e.g. lock after publish)
  • support read-only public manuals (is_public_external)

Summary

The Manuals app uses a clean, capability-driven permission model that:

  • is fully org-scoped
  • separates read/write/export/download concerns
  • integrates cleanly with DRF
  • aligns with the broader platform permission system

This provides a strong foundation for future access control and scaling.