Frappe app

Advanced Permission

Replaces role-and-permlevel access control with a no-code engine you configure per DocType — which rows a person sees, which fields inside them, what they can do, and how access propagates — enforced identically across the Desk, the REST API and MCP.

Where native permissions stop

Frappe's own model ends at role → DocType → permlevel. Advanced Permission lets you express the rest of the sentence, in a visual builder:

A Receivable User may read a Sales Invoice only if its customer has an outstanding balance — and even then, blur the cost fields and hide the timeline. Everyone else must request access, which auto-approves for their own department and expires in seven days.

Every decision is made on the server. The bundled client script only makes the screen match what the server already returned — it never grants anything.

What you get

Row scopesA visual AND/OR/NOT builder decides which records a door opens — by field, owner, reporting line, department, age, a linked record, or “I can access the linked doc”.
Six field levelsPer field: Hidden, Blur, Masked (show first/last N), Read-only, Editable, or Show. Values are removed on the server, so hiding is real.
Per-row child tablesBlur cells or drop rows of a child table for the rows a person may not see — restored on save, so nothing is lost.
Relationship scopesReports-to subtree, department, junction EXISTS, and dynamic-link “has access to the linked doc” at a chosen permission level.
Access requestsA restricted user can request more; requests route to approvers, can auto-approve by rule, and expire.
Route guardsBlocks the paths that bypass has_permission — file download, print / PDF, and email.
Anti-scraping and auditPer-window read and export caps, plus an access log of who did what.
A simulator“What can this user see, and why?” — the row condition, the counts, and the opening doors for one record.

Three words worth keeping straight

Access Rule

One per governed DocType. Decides whether the app governs it at all, and how its doors combine.

Door

A single grant inside a rule. Who (roles) × which rows (scope) × what they can do (profile).

Access Profile

A reusable bundle. The actions — read, write and the rest — and the default field access a door grants.

Safe to try

01

Installing changes nothing

A DocType with no enabled Access Rule is completely un-governed — Frappe's native permissions apply unchanged.

02

Build, save, simulate

Open the Access Rule Builder at /app/access-builder, add a door, then open the Access Simulator at /app/access-simulator to see exactly what a test user gets before anyone else does.

03

One tick reverses it

Turning off a rule restores native behaviour immediately. That's the escape hatch, and nothing is lost.

Enforced everywhere, not just on screen

Enforcement hooks the server document lifecycle rather than the browser, so the same decision applies whether a record is reached through the Desk, the REST API, or an MCP connector.

ListsFiltered by permission_query_conditions.
Single documentsChecked by has_permission.
Fields and child rowsRedacted on the read path, before the data leaves the server.
File, print and emailGuarded at the request layer — the routes that bypass has_permission in stock Frappe.
Both permission hooks fail safe. A bug is logged, lists fail closed, and single-document checks defer to native permissions. It can never silently leak data.

Full documentation is public

Concepts, row scopes, fields and child tables, cascade and link guards, access requests and recipes — plus enforcement and security, the Access Simulator, and a developer reference.