Understanding the Different Ways to Control Access Rights in Frappe

I’m trying to understand the different options available in Frappe for controlling user access to data and documents. I know there are several mechanisms, but I’m not sure when each one should be used.

Could someone explain, with a little detail, the purpose and typical use cases of the following (and anything else I may have missed)?

  • Role Permissions

  • User Permissions

  • Permission Query Scripts

  • Server Scripts

  • Document Sharing

  • Assignment Rules

  • Workflows and Workflow States

  • Has Permission hooks / Custom permission logic

  • Any other recommended approaches for restricting access

I’m particularly interested in understanding:

  • When to use each option instead of the others.

  • Which methods are best for restricting document visibility versus controlling actions (read, write, submit, etc.).

  • Whether there are any best practices or common pitfalls when designing a permission model in Frappe.

If anyone has a simple explanation or a comparison of these approaches, I’d really appreciate it.

1. Purpose & Use Cases

  • Role Permissions: Baseline access control. Defines what actions roles can perform on a DocType. (Use case: Sales User vs. Sales Manager).

  • User Permissions: Restricts data visibility horizontally based on master records. (Use case: Regional managers only seeing their territory’s data).

  • Permission Query Scripts: Injects SQL filters into database queries for complex relational visibility. (Use case: Users seeing documents only if they belong to a project team).

  • Server Scripts: Programmatic validation during data fetches or saves. (Use case: Blocking an action if custom dynamic conditions fail).

  • Document Sharing: Ad-hoc, record-specific access for users who lack general permissions. (Use case: Giving an external auditor read access to one Purchase Order).

  • Assignment Rules: Operational task delegation. (Use case: Auto-assigning support tickets to agents).

  • Workflows & States: Controls document lifecycle and action locks based on status. (Use case: Locking a document from edits once marked “Approved”).

  • Has Permission Hooks (has_permission): Backend Python override for complex, programmatic permission checks. (Use case: Time-based or highly contextual security).

2. Visibility vs. Actions

  • Restricting Visibility (What records users see): Use Role Permissions (baseline), User Permissions (master-data splitting), and Permission Query Scripts (complex relations).

  • Restricting Actions (What users can do): Use Role Permissions (CRUD), Workflows (state-based locks), and Server Scripts (field rules).

3. Best Practices & Common Pitfalls

  • Start Simple: Always use standard Roles first. Avoid over-engineering with custom scripts unless necessary.

  • Watch Performance: Heavy Permission Query Scripts slow down list views and reports. Keep them optimized.

  • Never Trust UI Hiding: Client-side UI hiding is for UX only. Always enforce security on the server side.