Email this post as a PDFDevelopment · 25 September 2026 · 5 min read

Permissions in Business Central: the security model, from entitlements to Access = Internal

There are four layers between a user and a table: the licence, the entitlement, the permission sets and the object's own access level. Most permission problems come from not knowing which layer said no. How each works, how to ship permission sets with an extension, why SUPER for everyone is not a plan, and how agents changed the picture.

Contents
  1. Layer 1: the licence and its entitlement
  2. Layer 2: permission sets
  3. Layer 3: permission sets shipped by extensions
  4. Layer 4: the object's own access
  5. Finding out which layer said no
  6. Record-level and field-level
  7. Agents changed the picture
  8. The administrator's routine

"The user cannot see the page" is the most common ticket on any Business Central support desk after go-live, and it is nearly always a permissions question with four possible answers. This is the model, layer by layer, and how an extension developer and a system administrator should each use it.

Layer 1: the licence and its entitlement

Each user has a licence (Essentials, Premium, Team Member, Device, External Accountant, and the system ones). Microsoft ships an entitlement object per licence that lists the maximum the licence may do: a Team Member's entitlement does not include inserting sales documents, however many permission sets you give them. This layer is Microsoft's and you cannot change it. When a Team Member "has the permission set but still gets an error", this is why. Who needs which licence covers the choice.

Layer 2: permission sets

A permission set is a named list of permissions: for each object (table data, table, page, codeunit, report, query, XMLport, system), which of Read, Insert, Modify, Delete and Execute are allowed, directly or indirectly (indirect means "only when called from code that has direct permission", which is how a user can post a sales order and write to G/L Entry without being able to edit G/L entries). Permission sets can include other permission sets, and exclude specific permissions, so you compose a role from building blocks.

Users are assigned permission sets per company (or all companies), and user groups (now "security groups", linked to Entra groups) assign sets to many users at once. The effective permission is the union of everything assigned. SUPER is the set that grants everything; it is for administrators and for nobody else, and "give them SUPER until we sort the permissions out" is the start of every permissions problem we are asked to untangle.

Layer 3: permission sets shipped by extensions

An extension that adds tables and pages has to say who may use them, or nobody can except SUPER. Since version 18 permission sets are AL objects:

permissionset 50100 "CON COURIER"
{
    Assignable = true;
    Caption = 'Contoso Courier';
    Permissions =
        tabledata "CON Courier Shipment" = RIMD,
        table "CON Courier Shipment" = X,
        page "CON Courier Shipments" = X,
        page "CON Courier Shipment Card" = X,
        codeunit "CON Courier Shipment Mgt." = X,
        report "CON Despatch Label" = X;
}

permissionsetextension 50101 "CON Sales Extends D365 SALES" extends "D365 SALES"
{
    Permissions = tabledata "CON Courier Shipment" = R;
}

Ship one assignable set per feature area, plus one that includes them all, and use permission set extensions to add your objects to Microsoft's standard sets (D365 BASIC, D365 SALES) so that existing roles keep working the day your app is installed. Mark internal-only sets Assignable = false. The AL permission-set generation tool (from the extension's objects) gets you a starting point; it grants too much, so trim it. And test as a user who is not SUPER; the pipeline should run the tests under a restricted permission set, which the test runner supports.

Layer 4: the object's own access

Independent of permissions, an object can declare who may reference it: Access = Public (default) or Internal (only this app, or apps listed in internalsVisibleTo). Internal is a compile-time boundary for developers, not a runtime security boundary; it is for keeping your implementation details out of other apps' reach, not for protecting data. Extensible = false on a table or page similarly stops other apps extending it. Use them to keep your API surface small.

Finding out which layer said no

The error text tells you. "You do not have the following permissions on TableData X: Insert" is layer 2 (or 3): a missing permission set. "Your license does not allow..." or a Team Member who has the set and still cannot post is layer 1. An AL compile error "cannot access internal object" is layer 4. The Effective Permissions page (from the user card) shows what a user actually has on an object and which set granted it, and is the first place an administrator should look, before changing anything.

Record-level and field-level

Security filters on a permission set restrict a user to records matching a filter (this salesperson sees only their customers). They are powerful and they are easy to make slow, because the filter applies to every read, so keep them on indexed fields. There is no native field-level security; hiding a field on a page is not security, and the API will still return it. If a field must be invisible to some users, that is a design question for a separate table.

Agents changed the picture

An AI agent (Sales Order Agent, Payables Agent) runs as its own user with its own permission sets, and it only does what those sets allow. That is the control: a Payables Agent that can create purchase invoices but not post them is enforced by permissions, not by prompt. It also means an extension that assumed every session was a human with a broad set may fail for an agent; ship permission sets that cover what the agent needs and test with an agent-shaped user.

The administrator's routine

  • Nobody has SUPER except two named administrators and the integration accounts that genuinely need it (most do not).
  • Roles are security groups mapped to Entra groups; joiners and leavers are handled in Entra, not on user cards.
  • New extensions ship their sets; the administrator assigns sets, never edits permissions by hand in the client (a hand-edited set is lost on reinstall).
  • A quarterly look at Effective Permissions for a sample of users, and at who has SUPER.
  • Before an audit, the User Permission Sets report, which is the list the auditors ask for.

Permissions are tedious and they are where "the system is secure" is actually true or not. If an extension you have inherited ships no permission sets, or every user has SUPER, both are findings in our health check, and both are a day to fix.

Email this post as a PDF
A branded PDF of this post, sent to your inbox to keep, print or share. Copy in colleagues if you like.
We only use these addresses to send this PDF. Nobody is added to a mailing list. Mike at Business Boxed receives a copy. See our privacy notice.
Email this post
Talk to us
Want this done in your Business Central?
Book a 30 minute callGet the monthly newsletter

Related posts