Security Model¶
Dataverse security is composed from a few building blocks. Design it deliberately and document the result in the project's architectural documentation — it's hard to retrofit and it depends on the table ownership decisions already made.
Building blocks¶
| Block | Use it for | DIGITALL guidance |
|---|---|---|
| Business units | Coarse data partitioning across org structure. | Keep the BU tree as flat as the data-access requirements allow; use the modern matrix data-access where org and data boundaries differ, rather than deep BU nesting. |
| Security roles | What a persona can do. | One role per persona, built from least privilege up. Don't edit out-of-the-box roles — copy and adjust (see DGT-CUS-230 below). |
| Teams | Sharing and group ownership. | Prefer Microsoft Entra group teams so membership follows identity governance. Use access teams for ad-hoc per-record sharing; owner teams when a team, not a person, owns records. |
| Column (field) security | A handful of genuinely sensitive columns. | Apply a field security profile to the specific columns; don't blanket-secure a whole table this way. |
| Hierarchy security | Manager-sees-reports access. | Enable only if the org actually needs it; it adds query cost. |
Principles¶
DGT-CUS-220— Least privilege. Start from no access and grant what a persona needs, scoped to the smallest ownership depth (User → BU → parent-child BU → Org) that works.DGT-CUS-230— Don't edit out-of-the-box security roles — copy and adjust. Platform updates change the originals underneath you; a customized copy keeps your changes and Microsoft's updates apart.DGT-CUS-240— No standing System Administrator for app/service accounts. Application users get a purpose-built role — see the service-principal connection guidance in Env Variables & Connection References and Governance & DLP.- Mark security roles
IsCustomizable = falsewhere they're not meant to be extended downstream (see Naming Conventions). DGT-CUS-250— Test with a real role, not as admin. System Administrator hides every privilege gap; validate forms, views, and plugins under the actual persona role before calling a feature done.DGT-CUS-260— Never implement security through UI visibility. A field hidden on a form, a removed navigation item, or a hidden button restricts nothing — the data stays readable and writable through the Web API. Use column-level security for sensitive columns and privileges/roles for operations; UI visibility is a usability tool, not a security boundary.DGT-CUS-270— Security roles are solution components and get deployed. Roles travel in the solution through every environment; they are never rebuilt or hand-edited in test/prod. A role difference between environments is a deployment defect, not a configuration task. See Microsoft's security guidance.
Auditing¶
Configure Dataverse auditing deliberately rather than leaving the defaults: decide per table (and where needed per column) what gets audited, and agree a retention period with the customer — audit logs consume log capacity and are a common silent cost driver. Also know that an environment restore does not bring audit logs back; if the audit trail is a compliance requirement, plan its preservation separately.
In code¶
Plugins run against either the calling user (SecuredOrganizationService) or elevated
(ElevatedOrganizationService) — that choice is a security decision. Prefer the secured
service so platform security still applies, and reach for elevated only with intent. See
DIGITALL Assembly.
Customer security standards take precedence
Where a customer has an existing security model or naming for roles/teams, follow it and document the deviation — see Scope & Principles.