Learn how to architect a production-grade Dataverse security model using business units, custom security roles, owner teams, access teams, and AAD-linked teams. This complete lesson covers real-world design patterns, privilege configuration, and troubleshooting for multi-team organizations.

Picture this: you've built a beautiful model-driven app for your sales organization. The data model is clean, the forms are well-structured, and the views show exactly what users need. Then your IT security contact calls. Regional sales managers should only see opportunities in their territory. The finance team needs read-only access to won deals but shouldn't touch anything. A small group of executive assistants needs to update records owned by the VP — records they don't personally own. And none of this should require custom code.
This is the moment where Dataverse security stops being an afterthought and becomes the feature you can't live without. Dataverse ships with a mature, layered security model built directly into the platform — one that governs not just who can log in, but what data each user can see, create, modify, and delete, down to the individual record. Getting it right means your app works correctly in production. Getting it wrong means sensitive data leaks across team boundaries, users can't complete their jobs, or your helpdesk drowns in "why can't I see this record?" tickets.
By the end of this lesson, you'll be able to architect a Dataverse security model for a real-world multi-team organization, assign and customize security roles with appropriate privilege levels and access scopes, structure business units to match your org chart, and use teams — including AAD group-linked teams — to handle exceptions and cross-team access without creating a maintenance nightmare.
What you'll learn:
You should already be comfortable with the basics: what Dataverse tables, rows, and environments are (if you need a refresher, Dataverse Fundamentals: Tables, Columns, and Rows Explained for Power Apps Makers has you covered). You should also have built at least one model-driven app — this lesson assumes you understand what you're securing. If that's new territory, start with Building Your First Model-Driven App: Site Map, Tables, Forms, and Views first.
Before touching a single setting, you need to understand the mental model. Dataverse security is additive and layered, meaning access is denied by default and permissions are granted by combining multiple security mechanisms. There are three primary layers:
Every authenticated user who accesses a Dataverse environment must have at least one security role assigned. Without a role, they get the dreaded "You do not have sufficient permissions to access Microsoft Dataverse" error even if their license is valid.
Security roles define privileges in two dimensions: the type of operation (Create, Read, Write, Delete, Append, Append To, Assign, Share) and the access scope (None, User, Business Unit, Parent: Child Business Units, Organization). Understanding these two dimensions is the foundation of everything else.
Key insight
"Append" and "Append To" are the pair that governs relationships. If you want a user to be able to associate a Contact with an Account, the user needs Append on Contact and Append To on Account. Forgetting this pair is one of the most common causes of mysterious relationship errors.
The access scope controls which records the privilege applies to:
These scopes are the key to building granular, org-aware security without writing a single line of code. A regional sales manager gets Business Unit scope on Opportunities — they see their own deals plus everyone on their regional team's deals. The VP of Sales gets Organization scope — they see everything.
Business units (BUs) are Dataverse's way of representing your organization's structure. Every environment has exactly one root business unit — it's created automatically and named after your tenant. Every user belongs to exactly one business unit. Record access inheritance follows the business unit tree.
Here's where many teams go wrong: they try to mirror the full corporate org chart with dozens of nested business units, then discover that managing it is a full-time job. The right design principle is this — only create business units at the boundaries where data must be isolated.
Consider a company called Meridian Financial with this structure:
Meridian Financial (root BU)
├── North Region
│ ├── New York Office
│ └── Boston Office
├── South Region
│ ├── Atlanta Office
│ └── Miami Office
└── Corporate
If advisors in New York should never see Atlanta's client records, you need BUs down to the office level. But if all North Region advisors can see each other's records, you only need the regional BUs. Don't add New York and Boston as separate BUs unless the data isolation actually requires it — every level you add multiplies your security role assignment surface.
Warning
Changing a user's business unit after they've created records does not re-parent those records. The records stay owned by the original business unit assignment. Moving users between BUs in a live system requires a careful data migration plan, not just a setting change.
To create a business unit in Power Apps (make.powerapps.com):
You can also do this through the Power Platform admin center at admin.powerplatform.microsoft.com under the environment's Security settings. The admin center route is generally preferred for new environments since Microsoft is progressively moving management features there.
Every user is assigned to a business unit when they're added to the environment. To change an existing user's business unit:
The user's security roles are typically removed when you move them to a new BU (since roles are BU-scoped), so you'll need to reassign their roles immediately after.
Note
The root business unit is special — users assigned there are effectively "above" the hierarchy and can be granted organization-wide access more easily. Many organizations put their IT admins and power users in the root BU to simplify their role assignments.
A security role is a named collection of privileges. Every table in your environment — standard tables like Account and Contact, plus any custom tables you've built — can have privileges defined for each operation type and at each scope level.
When you open a security role to edit it, you'll find several tabs organizing privileges by category:
Each cell in the grid shows a circle with a fill level — no fill means no access, one quarter fill means User scope, half fill means Business Unit scope, three-quarter fill means Parent:Child scope, and full fill means Organization scope. Clicking a cell cycles through the levels.
Let's build a security role for Financial Advisors at Meridian Financial. They work with custom tables: ms_ClientPortfolio, ms_InvestmentPosition, and ms_ClientNote. They should:
Here's how the role should be configured:
Custom Entities tab:
| Table | Create | Read | Write | Delete | Append | Append To |
|---|---|---|---|---|---|---|
| Client Portfolio | User | Business Unit | User | None | User | User |
| Investment Position | None | Business Unit | None | None | None | None |
| Client Note | User | Business Unit | User | User | User | User |
Core Records tab:
| Table | Create | Read | Write | Delete |
|---|---|---|---|---|
| Account | None | Organization | None | None |
| Contact | None | Organization | None | None |
Notice a few deliberate decisions here:
Tip
Set Read broader than Write when you want users to see records for reference but not accidentally modify them. This is especially useful for lookup fields — if a user can't Read a record at all, they can't even select it in a lookup field on a form.
A critical practice: never modify the out-of-the-box security roles like "Salesperson" or "System Administrator." If Microsoft updates them, your changes may be overwritten. Instead, copy an existing role as your starting point (select the role, choose Copy Role), then modify the copy. Name your custom roles with a clear prefix like your org name to distinguish them from system roles.
Warning
The System Administrator security role is the nuclear option — it bypasses all security role checks and grants full access to everything. Assign it only to environment administrators. Even developers building solutions should use a developer-level role, not System Administrator, unless they genuinely need it.
Users can have multiple security roles — privileges are combined additively. If a user has two roles and one grants User-scope Read on a table while the other grants Business Unit-scope Read, the effective access is Business Unit scope (the higher of the two).
To assign roles to a user:
You can also assign roles through the Power Platform admin center at a bulk level, which is more efficient for onboarding batches of users.
Business units handle hierarchical, structural isolation. But real organizations have messier access needs:
This is where teams come in. Teams are collections of users that can own records and hold security roles, giving you a flexible layer on top of the BU structure.
Dataverse has three types of teams:
An owner team can own records. When a record is assigned to an owner team (rather than an individual user), every member of that team gets access to that record based on the team's security roles.
This is powerful for shared workloads. Think of a "Key Accounts" team at Meridian Financial — the company's biggest clients need attention from multiple advisors, so these portfolio records are owned by the Key Accounts owner team rather than a single person. All team members can work on them without needing organization-wide access.
To create an owner team:
Key insight
When you assign a security role to a team, every member of that team gets those privileges for the duration of their membership. This means you can grant temporary elevated access by adding someone to a team, then revoke it cleanly by removing them — much cleaner than role reassignment.
An access team is lighter-weight — it cannot own records or hold security roles. Instead, it grants specific members access to a specific record. Access teams are automatically created per-record and are ideal for ad-hoc collaboration.
To use access teams, you first create an Access Team Template on a specific table, defining what level of access (Read, Write, Append) that template grants. Then on any individual record of that table type, you add users to that record's access team.
For example, at Meridian Financial, when a client portfolio goes into a complex restructuring review, you might add an outside counsel's user account to the access team for that specific portfolio record — giving them read access to that one record without opening up anything else.
Access teams show up as a subgrid on the form — users can be added directly from the record. This is a form configuration, so you'll need to add the Access Team subgrid to the relevant form in your app. If you need a refresher on adding subgrids to forms, Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms walks through that configuration.
This is where enterprise Dataverse security becomes genuinely scalable. An AAD group team links a Dataverse team to an Azure Active Directory security group or Microsoft 365 group. Membership is managed in Azure AD — when someone is added to the AAD group, they automatically get the team's security roles in Dataverse. When they're removed from the AAD group, access is revoked.
Why does this matter? Your IT department already manages group membership in Azure AD using your HR system, offboarding workflows, and identity governance processes. AAD group teams let Dataverse security ride on top of that existing infrastructure instead of creating a parallel manual process that inevitably gets out of sync.
To create an AAD group team:
Existing members of the AAD group who are also licensed Dataverse users will automatically gain those roles when they next authenticate to the environment.
Tip
AAD group teams are the recommended approach for production environments at any meaningful scale. Managing individual role assignments becomes untenable with more than 20-30 users. If your organization uses Entra ID (the renamed Azure AD), the same Object ID approach works — the underlying technology is the same.
Sometimes the requirement isn't "this user can't see this record" but "this user can't see this field on this record." Dataverse handles this with Column Security Profiles (formerly called Field Security Profiles).
You create a Column Security Profile, define which secured columns it grants access to and at what level (Read, Create, Update), then assign users or teams to that profile. By default, columns aren't secured — you have to explicitly enable security on each column.
A common use case: the ms_SocialSecurityNumber column on a Client table. You secure the column at the table level, then create two profiles:
Column security is separate from table security — a user can have full table-level Write access but still be blocked from updating a secured column if they lack the right profile.
To enable column security on a custom column:
Then go to Settings > Security > Field Security Profiles to create and assign profiles.
Warning
Enabling column security on a column that's used in business rules or calculated fields can cause unexpected behavior. Test thoroughly in a development environment before enabling in production. Also note that column security doesn't affect system administrators — they always see secured fields.
Dataverse also supports position-based and manager hierarchy security models that layer on top of the BU structure. When hierarchy security is enabled for a table, a manager can access records owned by their direct and indirect reports — even if those reports are in different business units.
This is configured at the environment level (Settings > Security > Hierarchy Security) and is particularly useful in sales organizations where the management chain matters more than the BU structure for record visibility.
The two modes:
We won't go deep on hierarchy security here, but know it exists. It's the right tool when your access requirements follow reporting lines rather than geographic or structural business units.
Let's design the complete security model for Meridian Financial's investment advisory application. The application uses the tables and relationships described in Designing a Dataverse Data Model: Relationships, Lookups, and Choice Columns, with custom tables for ClientPortfolio, InvestmentPosition, and ClientNote.
Meridian Financial (root BU)
├── North Region
├── South Region
└── Corporate
| Role Name | Primary Tables | Key Access Pattern |
|---|---|---|
| Financial Advisor | ClientPortfolio, ClientNote | BU-scope Read, User-scope Write/Create |
| Regional Manager | ClientPortfolio, ClientNote, InvestmentPosition | Parent:Child-scope Read/Write |
| Compliance Officer | All tables | Org-scope Read only, plus SSN column security profile |
| Portfolio Admin | All custom tables | Org-scope Read/Write/Create |
| IT System Admin | — | System Administrator role |
| Team Name | Type | BU | Purpose |
|---|---|---|---|
| North Region Advisors | AAD Group | North Region | Mirrors AAD group; auto-provisions advisor role |
| South Region Advisors | AAD Group | South Region | Mirrors AAD group |
| Key Accounts | Owner | Root | Owns records for strategic shared clients |
| Compliance Review | AAD Group | Corporate | Compliance officers with column-secured access |
A new advisor joins the Atlanta office. IT adds them to the "South Region Advisors" AAD group. On first login to the environment, they're automatically provisioned with the Financial Advisor security role, scoped to the South Region business unit. They can see all portfolios owned by users in the South Region BU, create new portfolios, and write notes — but they can't see North Region data, can't delete portfolios, and can't view SSN fields.
When a portfolio becomes a key account, an admin reassigns it from the individual advisor to the "Key Accounts" owner team. Now all members of that team can collaborate on it within their normal role permissions.
When a compliance audit starts, the auditor's account is added to the "Compliance Review" AAD group — they get read-only organization-wide access immediately. When the audit closes, they're removed from the group and access is instantly revoked. No IT ticket needed.
You'll build a working security model for a two-region organization with shared strategic accounts.
Setup: Use a developer environment (free at make.powerapps.com with a developer plan) with a custom table called ms_Project and a standard Account table.
Step 1: Create Business Units
Step 2: Create a Security Role
ms_Project: Create/Read/Write/Delete/Append/AppendTo all at Business Unit scopeStep 3: Create a second Security Role
ms_Project Create/Read/Write to Parent: Child Business Units scopeStep 4: Create an Owner Team
Step 5: Test the Model
Tip
Use the Run Diagnostics button on a user record in the classic admin interface to check what roles and teams a user has, and what their effective access is on any given table. It's the fastest way to verify your security model is working as intended before go-live.
Cause: The user has a security role but it grants User-scope access only, and all records are owned by other users or teams. Fix: Check record ownership. Run diagnostics. Consider whether the user needs Business Unit scope or whether the records need to be reassigned to a team the user belongs to.
Cause: Missing Append/Append To privileges. The user can read the parent record but can't traverse the relationship to child records. Fix: Grant Append on the child table and Append To on the parent table for that user's role.
Cause: The user has no Read access to the table being looked up, or their Read scope is too narrow. Fix: Ensure the user's role has at least Organization-scope Read on reference tables used in lookups. You want users to see the lookup options even if they can't otherwise interact with those records.
Cause A: Record is assigned to an owner team the user is a member of, and team's role has broader scope than intended. Cause B: User has been assigned multiple roles and one of them has broader access than intended. Fix: Check all teams the user belongs to and what roles those teams carry. Check all directly-assigned roles. Remember: privileges combine additively — the broadest scope wins.
Cause: Dataverse caches security tokens. Users may retain their old privileges for up to an hour after role changes. Fix: For immediate effect, ask the user to sign out and back in. In urgent situations, you can force a token refresh via Power Platform admin center. In production, always plan for a brief propagation delay.
Cause: Flows run in the context of the triggering user by default. If that user lacks the privileges the flow requires, it fails even if the flow "should" have access. Fix: Consider running flows "as service account" using an application user with appropriate permissions. This is a broader topic covered in Power Apps Security: Roles, Sharing, and Data Permissions.
Warning
Never grant broad permissions to debug a permission issue and forget to remove them. "Let's give them System Admin to see if it works" is how temporary fixes become permanent security holes. Use the Run Diagnostics tool to identify the specific missing privilege and add only that.
Cause: System Administrators always bypass column security. If you're testing as a sysadmin account, you'll always see secured fields regardless of profiles. Fix: Test with a non-admin account that has the "Basic User" or your custom role to verify column security behavior accurately.
Dataverse's security model is built on a clear mental hierarchy: environment access → security roles (defining what operations, at what scope) → business units (defining the organizational boundaries those scopes apply to) → teams (providing flexible cross-cutting access and AAD integration) → column security (field-level control where needed).
The key design principles to carry forward:
The next natural step is to look at how these security patterns interact with canvas apps and how sharing works differently when your data source is Dataverse versus SharePoint. If you're building model-driven apps that need solid security foundations, the patterns here apply directly.
You should also look at how business rules interact with your security model — security roles control access, but business rules enforce data quality, and the two layers work together to ensure data integrity across your application. And if you're thinking about governance at the environment level — who can create environments, which connectors are allowed, data policy — Canvas App Governance at Scale: DLP Policies, Connector Whitelisting, and Tenant-Wide Compliance Controls covers the organizational layer above what we've covered here.
A secure Dataverse application isn't just about passing an IT review. It's about building an application where the access model correctly reflects how the business actually operates — so users see exactly what they need, nothing they shouldn't, and your data stays trustworthy over the long run.