ERPNext field-level permissions with perm levels

Field-level permissions in ERPNext use perm levels and role permission rows to hide or lock sensitive fields such as cost, margin or salary. This page explains how to configure them, test each role's view and confirm the limits before go-live.

On this page

How ERPNext field-level permissions with perm levels protect cost and margin

Perm levels let you hide or lock individual fields such as cost, margin or salary while the rest of a document stays visible to the same role. In ERPNext, each field on a DocType carries a permission level (perm level), and roles are granted read, write, create, submit, cancel or amend rights per level. A sales user can therefore open a sales order, see items, quantities and customer terms, and still be unable to see the valuation rate or margin columns that sit on a higher perm level. The situation that usually prompts this is a finance or HR lead who needs broad visibility into transactions without exposing the numbers that drive pricing decisions or pay.

Perm levels apply to the fields of a DocType, including fields inside child tables, and they work alongside the role permissions that govern the DocType as a whole. Level 0 is the default for every field. Higher levels are assigned to specific fields, and a role only sees or edits those fields if it holds a permission row for that level. Use this approach when a role should see the document but not particular values in it. If a role should not open the DocType at all, plain role permissions are the right tool. If the same field should be visible to some users with the full value and to others in a partially hidden form, that is a masking question, and the sibling topic on Frappe data masking covers it. Confirm the exact field and child table behavior on your ERPNext version, since the Frappe documentation describes the mechanism but edge cases in reports, exports and list views need testing on your own site.

Choosing between perm levels, user permissions and masking

Access in ERPNext is easiest to design when you separate three questions. The first is whether a role can open a DocType at all, which is governed by role permissions on the document. The second is which records a user can see once they have that access, which is governed by user permissions on link fields. The third is which field values a role can read or edit within a record they already open, which is governed by perm levels on individual fields. Most access mistakes come from answering one question with a tool built for another.

  • Document access: Role permissions decide whether a role can read, write, create, submit, cancel or delete a DocType.
  • Record scope: User permissions limit a user to records linked to specific values such as a company, territory or branch.
  • Field scope: Perm levels control read and write rights on fields that share a level, for example cost or margin.
  • Order of evaluation: A user needs document access first, then record scope, and field rules apply to what remains visible.
  • Mixed cases: Sensitive values such as salary may need all three tools working together.

Confirm with your team which of the three questions each sensitive field actually raises before you choose a tool.

Setting up perm levels on a DocType step by step

This sequence takes one sensitive field, such as cost or margin, from an open field on a DocType to a tested rule where only the intended roles can read or change it. Each step ends with a check so the team knows the configuration matches the access design before it reaches users.

  1. Confirm the field and its access requirement

    Before touching any configuration, the implementation lead lists each sensitive field, the DocType it sits on, and the roles that need to read it, edit it, or never see it. Write this as a short access matrix and get sign-off from the business owner of the data. The step is done when every field has a named owner and a list of roles, and no field is left with an undefined audience.

  2. Set the perm level in the DocType customizer

    An administrator opens the DocType customizer for the target DocType and sets a perm level value on each sensitive field, leaving standard fields at level 0. Keep the number of levels small so the matrix stays readable. Confirm the exact menu path on your installed version, since labels change between releases. The check is that the field properties show the new perm level and that the DocType preview lists the field under the right section.

  3. Add role permission rows for each perm level

    In the DocType's permission table, add a row for each role and each perm level that needs access, then tick the read, write, create, submit, cancel or amend flags only where the role needs them. Rows at level 0 control the rest of the document, so a role that can read a sensitive field also needs level 0 read access to open the record. The check is that the table, filtered by perm level, lists exactly the roles in your access matrix.

  4. Save and clear the cache

    Save the customized DocType and clear the site cache so the new permission rules apply to active sessions. Because the change alters a standard DocType, make it through the customizer or a custom app, not by editing core files, so the configuration can be exported and reapplied after upgrades. The check is that the save completes without errors and the customization appears in the change log or export that your team keeps under version control.

  5. Create test users for each role

    Create one test user per role in the access matrix on a non-production site, with no extra roles and no User Permission restrictions beyond what production will use. Use role profiles only if production uses them. The check is that each test user has exactly one role set, which the team can verify on the user record before logging in.

  6. Verify what each role sees

    Log in as each test user, open a record of the affected DocType, and compare the visible fields with the matrix. Check the list view, the report view, the print format, and the export, because a field hidden on the form can still appear in reports if a report role has read access. The step is complete when every role sees the expected values, and any mismatch is logged with the role, field and document used.

  7. Test write and submit behavior

    As each test user, try to edit the protected field and, where relevant, submit or cancel the document. Confirm that roles without write access receive a read-only field and that roles with write access can save without errors. This is also the point to confirm how the rule behaves on documents already in the system, since existing values remain as they are. The check is a short written result for each role that matches the access matrix.

  8. Record the configuration and confirm the upgrade path

    Export the customization, record the perm level assignments and role rows in the team's documentation, and list the test results alongside them. Ask the implementation partner or your internal team to confirm the steps for the installed ERPNext version, because menu labels and defaults can differ. The check is a repeatable procedure that a second administrator could follow on a fresh site and reach the same result.

How role rows and perm levels combine for each role

This table maps three sample roles against perm level 0 and a restricted perm level on a hypothetical Purchase Order DocType, showing read, write, create and submit flags. Read it as a pattern rather than a configuration to copy: a role sees a restricted field only when its permission row for that perm level grants read. The main takeaway is that a missing row for the restricted level hides the field, even when the role can edit the rest of the document.

Role (illustrative)Perm level 0: read, write, create, submitPerm level 1 (restricted fields): read, write, create, submitWhat the role sees in restricted fields
Sales userRead, write, create, submit: yes, no, no, noNo row for perm level 1Hidden: cost and margin fields are not shown
Purchase managerRead, write, create, submit: yes, yes, yes, yesRead, write: yes, yes, no, noVisible and editable, but cannot create new restricted rows
HR managerRead, write, create, submit: yes, yes, yes, noRead: yes, write: yes, create: no, submit: noSalary-related fields visible and editable on existing records
System ManagerRead, write, create, submit: yes, yes, yes, yesRead, write, create, submit: yes, yes, yes, yesFull access, which is why this role should be limited
Auditor (read-only)Read: yes, write: no, create: no, submit: noRead: yes, write: no, create: no, submit: noRestricted fields visible without any editing rights
Role with no matching rowRead: yes on standard fieldsNo row for perm level 1Hidden, regardless of other permissions on the DocType

Testing what each role sees before go-live

Perm levels only work if each role sees exactly what its row allows, and the only reliable way to confirm that is to log in as each role and check every surface where the field can appear. The cards below cover the test cases to run, the staging setup they need, and the evidence to keep for review.

Set up one test user per role

Create a dedicated test user for every role that touches the sensitive DocType, and assign only the roles that a real employee in that job would hold. Avoid testing with Administrator or a System Manager account, because those accounts bypass the restrictions you are trying to prove. Record the role list for each user so the test results can be matched to the permission matrix later. Re-create the users after any role change, since a permission row that looks correct on paper can still be overridden by a user permission or a second role the test user carries.

Check the form view

Open a saved document as each test user and confirm that fields at the restricted perm level are hidden or read-only as designed. Include the fields that appear only after a status change, such as cost or margin fields that show on submitted documents. Try to edit a read-only field through the form and confirm the save is refused. Check the sidebar, comments and version history too, because a restricted value can leak through a timeline entry even when the field itself is hidden.

Check list and report views

Restricted fields often reappear in list view columns, sidebar filters, group-by counts and standard reports. Log in as each role, open the list for the DocType, and add or inspect columns and filters that reference the restricted field. Run the standard reports that draw on the same DocType, since report permissions are evaluated separately from form permissions. A value that a role cannot read on the form but can filter on in a list can still reveal its contents by trial and error, so test filters as well as columns.

Check print formats and exports

Print formats and data exports are the most common gaps in a field-level design. Generate the print format for each role and check whether the restricted value appears in the header, totals, or attached templates that were copied from another site. Then run the Data Export tool and the list export as each role, and confirm the restricted columns are absent from the file. Repeat the check for any email sent from a document, because the rendered print format is often attached automatically.

Check API responses and child tables

Call the REST endpoints for the DocType with each test user's API key or session and inspect the returned JSON for restricted fields. A field that is hidden in the UI may still appear in a response if the permission check was not applied to that path. Test child tables separately, because a restricted field inside an item row or a timesheet row may be exposed even when the parent document is locked for that role. Keep the request and response pairs as evidence.

Record the evidence and retest

Keep a dated test log that lists each role, test user, DocType, surface tested, expected result and actual result, with screenshots or saved responses where the result matters. Run the full matrix on the staging site with production-like data and roles, since permissions behave differently with real volumes and customizations. Repeat the matrix after every upgrade, custom field addition or new role assignment, and ask your team to confirm which evidence the auditor expects to see before you start.

Security and operational risks of field-level rules

Field-level permissions only protect data on the screen they govern. The risks below are the paths around that screen, and the changes over time that quietly reopen them. Review each one as part of every role change and upgrade.

Leaks through reports and exports

A locked field on the form can still appear in a Report View, Query Report, or a data export if the role can open that report or list. Check which reports and list views include cost, margin or salary columns, and confirm the role's report access before assuming the field is hidden. Run each sensitive report as a test user in the restricted role and compare the output with the form.

Exposure through API endpoints

Permissions enforced in the desk UI also apply to the REST API, but an integration user with broad read rights can return every field of a document, including those hidden in the form. Audit API keys and integration users, and list which DocTypes they can read. Avoid running integrations under System Manager or Administrator accounts.

Print formats and attachments

Print formats render fields from the document regardless of what the viewer sees on screen, so a restricted user who can print or email a document may receive cost figures. Review the print formats attached to each DocType and remove sensitive fields from any format sent to outside parties. Check attachments and linked files as well, since they are not governed by perm levels.

Linked documents reveal values

A user who cannot read a sensitive field may still see it through a linked document, a child table shown in another form, or a dashboard that aggregates totals. Map the links from each sensitive DocType and test whether a restricted role can reach the values through a related record. Hide or restrict the linked DocType where the value must stay private.

Role sprawl undoes field locks

Each new role or added permission row can widen access to a field that was previously locked, especially when a user holds several roles and ERPNext applies the most permissive combination. Limit which users can assign System Manager, review role profiles against job functions, and check the effective permissions of any user who gained a role. Small role changes over time often cause more exposure than the original design.

Drift after upgrades and customizations

Custom fields, scripts and app changes can add new sensitive fields without perm levels, and an upgrade can alter defaults or the DocTypes an app ships. Re-test the role matrix after each ERPNext or custom app upgrade, and treat new custom fields as unprotected until a reviewer sets their permissions. Keep the role matrix in version control so that changes can be compared and reversed.

Questions teams ask before configuring field-level permissions

Can our own team configure perm levels in ERPNext without a partner?

Yes, a team with a working ERPNext site and an administrator who understands roles can set perm levels on DocType fields in the Customize Form tool and in the DocType permission tables. The work itself is small per field. The risk sits in the role matrix: a field set to a higher perm level is hidden or read-only for every role that lacks a matching permission row at that level, so a mistake can block users from entering data they need. Teams without a documented role matrix and a staging site usually find the second and third passes take longer than the first.

What drives the effort for field-level permissions?

Effort scales with the number of DocTypes that carry sensitive fields, the number of roles that touch those DocTypes, and the reports, print formats, dashboards and integrations that read the same fields. Each DocType with a cost, margin or salary field needs its permission rows reviewed for every role, and each report that exposes those fields needs its own check. Custom scripts or API integrations that read restricted fields add another review, because permission rules on the desk do not automatically govern every code path. Ask any provider to list the DocTypes, roles and integrations in scope before agreeing a number.

How long does testing take for a field-level permission change?

Testing length depends on how many roles and sensitive fields you have, and how many test users you can set up on a non-production site. A small change to one DocType and two roles is a short test cycle. A change that spans sales, purchasing, stock and payroll roles means testing each role against create, read, write, submit and cancel actions, plus reports and exports. Ask for the test scope in writing: which roles, which DocTypes, which reports, and whether the test includes integrations and API access.

What must we provide before field-level permission work starts?

Three things make the work predictable. First, a role matrix that lists each role, the DocTypes it uses, and the fields it may see, edit or never see. Second, sample users for each role, with realistic but non-production data, so every role can be tested as it will really work. Third, a staging site on the same ERPNext version as production, with a recent copy of the data or representative test records. Without a staging site, changes are tested in production, which makes rollback and user communication harder.

Does a fixed-scope engagement cover field-level permission configuration?

A fixed-scope engagement can cover it when the scope, deliverables and timeline are agreed in writing before work starts. Typical written items are the DocTypes and fields in scope, the roles and sample users used for testing, the test cases and their results, and the handover documentation. Anything outside that list, such as new roles, extra reports, or custom scripts that touch restricted fields, should be added through a written change to scope. DeployOpen does not publish a price list, so the quote follows from the written scope.

What recurring work follows ERPNext upgrades for permissions?

Each ERPNext or Frappe upgrade can change standard DocTypes, add fields, or alter how permissions apply, so the permission matrix needs a regression pass after every upgrade. The Frappe supported versions page lists which major versions are supported and when each reaches end of life, which sets the pace for planning those passes. ERPNext also receives frequent minor releases on GitHub, so teams should decide whether to apply them on a set cadence. Ask your provider whether the retainer covers permission regression tests after upgrades and whether new roles or DocTypes trigger a scope change.

Is there a risk that field-level permissions expose data through other paths?

Yes. Perm levels control what a role sees on the form, but reports, list views, exports, API responses and server scripts can read fields through other paths. Server Scripts in version 15 and later are disabled by default and must be enabled through the server_script_enabled setting, so confirm whether they are on in your site before assuming coverage. Check each report and integration that reads sensitive fields, and test API access with a user from each role. Treat field permissions as one control in a wider access model, not a complete one.

How DeployOpen scopes and delivers field-level access work

Every engagement starts with a written scope that names the sensitive fields (cost, margin, salary or similar), the roles that should see or edit each one, and the test cases that will prove the result. Before any configuration, the team agrees which DocTypes are involved, which fields carry a perm level, and which roles hold read, write, create or submit rights at each level. This list is the working contract. It also tells you where the rules are hard to get right, such as a field that appears on several DocTypes, a child table that carries the same value, or a report that exposes the figure in a total. Most engagements are fixed-scope, so the scope, deliverables and timeline are agreed in writing before work begins, and changes to the field list are handled as a written change to that scope.

Configuration then happens on a staging site, not on production. DeployOpen assigns perm levels, adjusts the role rows and runs each test case as each role in the agreed matrix, then produces a role-by-field test record showing what every role sees and can change. Ask for that record in a form your reviewers can re-run, and confirm that the test accounts reflect the roles your users really hold, including any roles inherited through role profiles or LDAP group mapping. The record documents configuration and testing. It is not an audit report, an attestation or a certification, and it does not replace an assessment by an independent auditor or certification body. If your controls must be evidenced for an external review, confirm with your auditor which artifacts they will accept.

Ongoing support is available as a retainer. Permissions drift as new fields, reports and custom apps are added, and as ERPNext releases change behavior, so a retainer can cover re-running the role-by-field tests after upgrades, reviewing new custom fields for sensitivity and handling access requests. Ask whether a quote separates the one-time build and testing from recurring review, and what triggers a re-test.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.