Understanding the Dataverse Security Model: A Complete Practical Guide

If you’ve ever had a user complain they can’t see a record they “should” be able to see — or a manager who suddenly sees data they shouldn’t — welcome to the Dataverse security model.

Dataverse security is a layered, additive system. It’s not a single toggle or permission. Every data request passes through multiple layers before Dataverse decides what you can read, write, or delete. Understanding all the layers — and how they interact — is what separates someone who can configure security from someone who understands it.


The Six-Layer Security Architecture

Think of Dataverse security as six concentric rings. Every data request must pass through each one in order.

🌐 Layer 1 — Environment Access

Who can enter this Power Platform environment? (Entra ID + Environment security group)

FIRST CHECK

🏗️ Layer 2 — Organization / Root BU

The top-level container — one per environment. Licenses are validated here.

CONTAINER

📁 Layer 3 — Business Unit

Logical security partitions. Users belong to exactly one BU.

BOUNDARY

🔑 Layer 4 — Security Role + Access Level

What tables can I act on, and at what scope? (User / BU / Parent-Child / Org)

PERMISSIONS

📄 Layer 5 — Record Ownership & Sharing

Who owns this specific row? Has it been shared with me?

OWNERSHIP

🔒 Layer 6 — Column / Field Security Profile

Even within a record I can access — are all columns visible to me?

FINEST GRAIN

Important Note — Permissions are CUMULATIVE and ADDITIVE. If a user has two security roles, they get the union (most permissive) of both. There is no “deny” permission in Dataverse — you cannot take away access already granted by another role. The only exception is field security profiles, which can restrict individual columns independently of the role model.

Here’s how the core building blocks relate to one another:

ConceptPurposeScopeContains
UserIndividual identity in DataverseEnvironment1 BU, N roles, N teams
Business Unit (BU)Security boundary / partitionEnvironmentUsers, Teams, child BUs
Owner TeamGroup that can own records1 BUUsers, Security Roles
Access TeamTemporary sharing group1 BUUsers (no roles)
Azure AD Group TeamAuto-managed via Entra ID1 BUEntra group members
Security RoleBundle of privileges + access levelsBU or OrgTable & misc privileges
Field Security ProfileColumn-level access controlEnvironmentUsers, Teams

Users — Types, Licenses & Record Ownership

Every person or system that interacts with Dataverse is a User, synchronized from Microsoft Entra ID. Users must be licensed and belong to exactly one Business Unit.

User TypeDescriptionKey Points
Regular UserHuman users with an Entra ID accountMust have Power Apps or D365 license; belongs to exactly one BU
Application UserService principal / app registrationUsed by integrations and APIs; does not consume a named user license
System UserBuilt-in system account (SYSTEM, INTEGRATION)Cannot be disabled; used internally by Dataverse
Delegated AdminPartner/MSP admin with delegated accessCan manage environments without consuming customer licenses

Important Note: Every user belongs to exactly ONE Business Unit. When a user is moved to a different BU, their security role assignments may need re-evaluation because roles are BU-scoped.

When a user creates a record in a user-or-team owned table, they automatically become the owner of that record. This owner determines which other users can access the record based on their access-level settings.

Practical Scenario — Contoso CRM: Contoso has three departments: Sales, Support, and Finance — each is a Business Unit. A Sales rep creates a Contact record and owns it. A Support rep with only User-level Read on Contacts will not see this record unless it’s shared with them, or they have BU/Org-level access.

Important Note: In the Default environment, every licensed user automatically receives Basic User and Environment Maker roles. In Trial and Developer environments, this auto-assignment does not apply — you must assign roles manually.


Business Units — The Security Boundary

Business Units are the primary organizational unit for security in Dataverse. They create a hierarchical boundary that controls how much data users can see.

CONTOSO — BUSINESS UNIT HIERARCHY
🌐 Root BU: Contoso (Organization)
auto-created · cannot be deleted
📁 Sales BU
Alice, Bob, Charlie
📂 EMEA Sales
Diana, Ethan
📂 APAC Sales
Fatima, George
📁 Support BU
Hannah, Ivan
📁 Finance BU
Julia, Kevin
Root Child BU Grandchild BU

BU rules you must know:

RuleDetail
One root BU per environmentCreated automatically; its name = Organization name
Users belong to exactly one BUA user cannot be in Sales BU AND Support BU simultaneously
Security roles are BU-scopedA “Sales Rep” role in Sales BU is a different instance from one in Support BU
Records have an owning BUWhen a user owns a record, the record’s owning BU = the user’s BU (by default)
Deleting a BUA BU must be empty (no users, teams, or child BUs) before it can be deleted
Disabling a BUDisables all users in that BU — they cannot log in; records remain intact

Who can see what? Alice (Sales BU) creates Contact “John Smith”:

  • Bob (Sales BU) with Business Unit Read → ✅ Can see it
  • Hannah (Support BU) with Business Unit Read → ❌ Cannot see it
  • Hannah with Organization Read → ✅ Can see it
  • Diana (EMEA Sales, child of Sales BU) with Parent:Child BU Read → ✅ Can see it

Important Note — Modern BUs: Microsoft introduced “Allow record ownership across business units.” When enabled, a user can own records in a BU different from their own, without needing organization-level access. This decouples record ownership from the BU boundary — useful for large matrix-style organizations.


Teams — Owner, Access & Azure AD Group

Teams are the second mechanism (after BUs) for grouping users in Dataverse. There are three types, each with distinct behavior.

🏆 Owner Team
Can own records
Security roles can be assigned
Members inherit team’s roles
One default team per BU
Records owned by team →
all members can access

Good for: Shared dept ownership

🔓 Access Team
Cannot own records
No security roles assigned
Used for ad-hoc, per-record sharing
Auto-created via template
Lightweight: temporary access
to one specific record

Good for: Sharing one contract

☁️ Azure AD Group Team
Can own records
Security roles can be assigned
Backed by Entra ID group
Membership auto-synced
IT manages groups →
Power Platform inherits

Good for: Large-org auto-management

Important Note: Access teams do not have security roles. They only grant access to specific records through sharing. If you need permanent role-based access for a group, use an Owner team or Azure AD Group team.

Access Team Templates — Per-Record Sharing at Scale

The Teams section above introduced access teams as a mechanism for per-record sharing. But the construct that makes them repeatable and manageable in practice is the Access Team Template — and this is what you actually configure.

The problem they solve: Manually sharing individual records with individual users creates hundreds of one-off sharing entries that are hard to audit and impossible to revoke consistently. Templates give you a structured, table-level pattern you apply per record.

Three-Step Setup

Step 1 — Enable Access Teams on the table.

In make.powerapps.com → Tables → [Your Table] → Properties → Advanced options, toggle on Access Teams. This tells Dataverse the table supports template-based access team records.

Step 2 — Create the template.

In Power Platform Admin Center (or Settings → Templates → Access Team Templates):

FieldExample Value
NameLegal Review — Opportunity
TableOpportunity
PrivilegesRead, Write, Append
DescriptionGrants legal team review access to a specific deal

The privileges here are the maximum a member will have — on that one record only. No broader role is inherited.

Step 3 — Add the subgrid to your form.

Add a Users subgrid tied to your template on the record’s form. Users and admins add/remove people directly on the record — no admin portal required.

What Happens at Runtime

When the first user is added to an access team for a record, Dataverse auto-creates one team instance for that record — regardless of how many members get added. So if 5 Opportunities each have 2 legal reviewers, you end up with 5 auto-created team instances (one per record), each with 2 members — not 10. Additional members are simply added to the same team instance for that record.

Opportunity: Contoso Enterprise Deal
 └─ Access Team: "Legal Review — Opportunity" [auto-created for this record]
      └─ Members: sarah@contoso.com, legal-lead@contoso.com
         Privileges: Read + Write + Append (on THIS record only)

If legal reviews 40 out of 500 Opportunities, Dataverse auto-creates exactly 40 team instances. These are lightweight system objects — Dataverse handles them at scale and cleans them up automatically when the record itself is deleted. You’ll see them listed in the Teams area of the Admin Center with auto-generated names — this is expected and they are not meant to be managed manually.

Access Team Template Rules

RuleDetail
Privileges are record-scopedRead on that one Opportunity only — not all Opportunities
No security rolesTemplates define privilege levels only — members get no role
Template is table-specificA “Legal Review” template on Opportunity is separate from one on Contract
Access levels don’t applyNo BU scope — access is to the specific record the team was created for
Removing a memberRemove from the subgrid — access to that record is immediately revoked

Important Note — System Administrator bypass: Sys Admins always have access regardless of access team membership. Access team templates only affect non-admin users.

Contoso requires Legal sign-off before any deal over $500K closes. Here’s exactly how the setup works end to end, and where everything lives.

Step 1 — The template lives at the environment level.

In Power Platform Admin Center → Settings → Templates → Access Team Templates. This is a one-time setup. You define the template name, which table it applies to (Opportunity), and what privileges members get (Read + Write). This template is then available across all records of that table.

Step 2 — The subgrid is added to the Opportunity form.

In make.powerapps.com → Tables → Opportunity → Forms → open the main form → add a subgrid component tied to your “Legal Review” template → publish. This is also a one-time setup by a maker or admin.

Step 3 — Adding a user happens on the record itself.

When a deal needs legal review, the sales manager opens that specific Opportunity, finds the “Legal Review” subgrid on the form, and adds the legal reviewer by name. No admin portal, no security role changes needed. The reviewer immediately gets Read + Write access to that one record only.

What legal sees: Only the Opportunities they’ve been explicitly added to — nothing else appears in their views or lists.

What about the $500K condition? The template has no built-in conditions — it’s just the access definition. The condition is either enforced manually (the manager decides when to add someone) or automated via a Power Automate flow that watches the Opportunity value and calls the “Grant Access” action when the threshold is crossed. The template works the same either way.

Important Note — Removing a user: Open the record, find the subgrid, remove them. Access is revoked instantly. However, removing a member does not delete the auto-created team instance — the team stays associated with the record (now empty) until the record itself is deleted, at which point Dataverse cleans it up automatically.

Important Note — One team per record, not per member: Dataverse auto-creates one team instance per record the first time a member is added — not one per member. So 5 Opportunities with 2 legal reviewers each = 5 team instances, each with 2 members. You’ll see these in the Teams area of the Admin Center with auto-generated names — this is expected and they are not meant to be managed manually.

Choosing the Right Sharing Method

ScenarioMethodWhy
One-off exception — just let Diana see this one recordManual ShareFastest, no setup needed
Repeatable business process with specific people per recordAccess Team TemplateStructured, auditable, revocable
Rules-based — share all new Accounts in Region East automaticallyPower Automate + Grant Access actionLogic-driven, no human in the loop
Permanent cross-BU access for a groupOwner Team or Azure AD Group TeamTemplates are per-record only — for permanent access, use a team with a role

Important Note — Templates vs Manual Access Teams: You can create “manual” access teams (type: Access Team) directly in the Teams list without a template. These work the same way but aren’t tied to a specific table or record form. Template-based access teams are the recommended pattern for anything repeatable — they’re discoverable on the record form, auditable, and manageable by non-admins without going into the Admin Center.


Azure / Entra ID Group Integration

Entra ID integrates with Dataverse at two distinct levels.

Level 1 — Environment-Level Security Group: Associate an Entra ID Security Group with an environment in the Power Platform Admin Center. Only group members can access the environment — everyone else is blocked, even with a valid license.

Level 2 — Azure AD Group Teams:

Group TypeSupported?Notes
Security Group✅ YesMost common; used for access control
Microsoft 365 Group✅ YesAlso works; tied to Teams and SharePoint
Dynamic Security Group✅ YesMembers auto-added based on Entra attributes (dept, job title…)
Distribution List❌ NoEmail-only groups; not supported

Enterprise Pattern: Create one Entra ID Security Group per BU → create an Azure AD Group Team in Dataverse for each → assign the security role to the team → add/remove users in Entra ID → Dataverse access follows automatically. No manual role assignment per user needed.

Important Note — Dynamic Groups: If your Entra group has a dynamic rule like department = "Sales", any new hire in Sales automatically gets Dataverse access and the correct security role — without any admin action in Power Platform.


Security Roles — The Heart of Dataverse Security

Security roles bundle privileges (what you can do) with access levels (how many records you can do it on). They are assigned directly to users, to Owner Teams, or to Azure AD Group Teams.

When you open a security role editor, you’ll find four tabs:

TabContentsWhat to Configure
TablesAll Dataverse tables (standard + custom)Create, Read, Write, Delete, Append, Append To, Assign, Share + access level per table
Miscellaneous PrivilegesCross-table actions”Export to Excel”, “Print”, “Bulk Delete”, “Web Access”
Privacy-related PrivilegesData exfiltration risks”Export Data to Excel”, “Bulk Detect Duplicates” — grant carefully
Business ManagementAdmin-level actionsManage BUs, Manage Teams, Manage Security Roles

Member’s Privilege — Controlling Team Role Inheritance

Every security role has one property that sits quietly above the privilege grid and is almost universally overlooked: Member’s Privilege. It has two options — Direct User (Basic) and Team Privileges and Team Privileges Only — and choosing the wrong one produces access behaviour that looks completely broken, because the role’s access level appears to be ignored.

This setting only activates when a role is assigned to an Owner Team or Azure AD Group Team. It has no effect when a role is assigned directly to a user.


Direct User (Basic) and Team Privileges

When a role carries this setting, every team member inherits its privileges as if the role were assigned to them personally. The access level scope on each privilege — User, Business Unit, Parent-Child BU, Organization — applies in full, from the individual user’s perspective.

Example — EMEA Sales Team with BU-level Read on Contact:

The role is configured with Business Unit-level Read on the Contact table and set to Direct User (Basic) and Team Privileges. It is assigned to the EMEA Sales Team Owner Team.

  • Alice joins the team → she can read all Contacts in the EMEA Sales BU — her own, her colleagues’, everyone’s in the BU.
  • Bob (same BU, same team) creates a new Contact → Alice can see it immediately, because BU scope covers all records in the same Business Unit.

This is the default option and the behaviour most people expect from team-based role assignment.


Team Privileges Only

This option is where the misunderstanding usually happens — and the role mockup above is the reason why.

The role still shows Business Unit Read on the Contact table. At first glance, that reads as “members can read all Contacts in the BU.” But with Team Privileges Only selected, the BU scope on the privilege is overridden by a team ownership filter. Dataverse does not evaluate the access level to determine which records a member can see. Instead, it asks a single question first: is this record owned by the team? Only if the answer is yes does the member get access.

Same role, same BU-level Read, different Member’s Privilege setting:

The role is now set to Team Privileges Only and assigned to the same EMEA Sales Team.

  • Alice joins the team → she can read only Contacts owned by the EMEA Sales Team itself.
  • A Contact owned by Alice personally? Not accessible through this role.
  • A Contact owned by Bob (a BU colleague)? Also not accessible.
  • A Contact assigned directly to the EMEA Sales Team? ✅ Accessible.

Why does the access level still appear on the role?

Two reasons. First, if the same role is ever assigned directly to a user (bypassing a team), the BU scope applies normally — the user gets full Business Unit-level Read. The Team Privileges Only flag only suppresses the scope when the privilege arrives via team membership. Second, the access level still acts as a ceiling. If you set it to User rather than Business Unit, even team-owned records outside that narrow scope would be blocked. In practice, Team Privileges Only roles are typically configured with a broad scope (Business Unit or Organization) and rely on team ownership to do the real narrowing.


Side-by-Side Comparison

Record ownershipDirect User / Team PrivilegesTeam Privileges Only
Owned by the user personally✅ Accessible (User scope)❌ Not accessible via this role
Owned by a BU colleague✅ Accessible (BU scope)❌ Not accessible via this role
Owned by the team itself✅ Accessible✅ Accessible
Role assigned directly to a user (no team)✅ Works normally — BU scope applies✅ Works normally — BU scope applies

Practical Scenario — Deal Desk at Contoso

Contoso’s Deal Desk team jointly processes large Opportunities. The requirement is that team members can work on deals assigned to the team, but should have no visibility into Opportunities owned by individual Sales reps in the same BU.

Setup:

  1. Create a role with Team Privileges Only and Business Unit-level Read, Write, and Create on Opportunity. Assign it to the Deal Desk Owner Team.
  2. When a deal reaches the Deal Desk, assign the Opportunity record to the Deal Desk team (not to an individual).
  3. Deal Desk members can now read and edit those Opportunities.

What they can and cannot see:

Deal Desk member (Alice)
 ├─ Opportunity owned by Deal Desk Team  → ✅ Read + Write
 ├─ Opportunity owned by Sales Rep Bob   → ❌ No access
 └─ Opportunity owned by Alice herself   → ❌ No access via this role

Even though the role says “Business Unit Read”, Alice gets no free access to the wider BU. The team ownership filter locks her scope down to team-owned records only. This is exactly the behaviour Team Privileges Only is designed for — a clean, auditable access boundary enforced by record ownership rather than BU membership.

Important Note: Team Privileges Only does not affect records the user can access through other roles assigned to them directly. If Alice also has a separate Sales Rep role with User-level Read on Opportunity, she can still see her own Opportunities through that role. Dataverse access is always additive — the most permissive combination of all assigned roles applies.

Example — Sales Representative role on the Contact table:

Create    → Business Unit   // Can create contacts for anyone in their BU
Read      → Business Unit   // Can read all contacts in their BU
Write     → User            // Can only edit contacts they own
Delete    → None            // Cannot delete contacts
Append    → Business Unit   // Can relate contacts to other records in BU
Append To → Business Unit   // Others can relate records to their contacts
Assign    → Business Unit   // Can reassign contacts within BU
Share     → Business Unit   // Can share contacts with others in BU

All 8 Table Privileges Explained

Every Dataverse table supports eight privilege types — the atomic building blocks of what a user can do.

📖

Read

View records in this table.
Without Read, the user
sees nothing at all.

✏️

Write

Modify existing records.
Creating is separate.
Write ≠ Create.

Create

Create new records in
this table. Independent
from Write privilege.

��️

Delete

Permanently remove records.
Grant carefully —
deletions are hard to undo.

🔗

Append

Attach THIS record to
another (N-side). e.g.
Link a Contact to
an Account.

Child-side privilege
📎

Append To

Allow records to attach
TO this (1-side). e.g.
Allow Contacts to be
linked to my Account.

Parent-side privilege
🔄

Assign

Transfer ownership of
a record to a different
user or team. Record
moves to new owner.

Changes ownership
🤝

Share

Share a record with
another user/team giving
temporary access without
changing ownership.

Keeps original owner

Append vs Append To — The Pair You Must Understand

This is the most commonly misunderstood privilege pair in Dataverse. Let’s make it concrete.

The mental model: Read the privilege name from the perspective of the table it lives on.

  • Append on Table A → “Table A’s records can be attached to something else.”
  • Append To on Table B → “Table B’s records can have things attached to them.”

In plain terms: Append is the privilege of leaving. Append To is the privilege of receiving.

THE RELATIONSHIP MODEL — APPEND vs APPEND TO
📄
CHILD TABLE
(Contact, Note, Task)
APPEND
”I can be linked to a parent”
user links them
Both privileges
required
🏢
PARENT TABLE
(Account, Case, Opportunity)
APPEND TO
”Things can be linked to me”
🧩 You always need BOTH. Append without Append To = save error. One without the other = broken relationship.

Worked Examples

Example 1 — Linking a Contact to an Account

Alice sets the “Account Name” lookup on a Contact, linking it to Contoso Ltd.

TableRolePrivilege NeededWhy
ContactChild — being attachedAppendThe Contact is leaving its standalone state and being linked outward
AccountParent — being linked toAppend ToThe Account is receiving the Contact; it needs to allow things to attach to it
  • ✅ Both present → link is created
  • ❌ Append only (no Append To on Account) → error when saving
  • ❌ Append To only (no Append on Contact) → error when saving

Example 2 — Attaching a Note to a Case

TablePrivilegePlain English
Note (child)Append”This Note is allowed to be attached to something else (the Case)“
Case (parent)Append To”The Case is allowed to have things attached to it (the Note)”

Example 3 — Many-to-Many Relationships (e.g., Opportunity ↔ Competitor)

In an N:N relationship, each side can act as either parent or child depending on direction — so both tables need both privileges.

TableNeeds Append?Needs Append To?
Opportunity✅ Yes✅ Yes
Competitor✅ Yes✅ Yes

Common mistakes:

MistakeWhat HappensFix
Only giving Append, forgetting Append ToSave error or lookup silently failsAlways grant both — they travel as a pair
Confusing Append with WriteWrite = edit a record’s own fields. Append = link it to another record.Think: editing vs relating
Thinking Append/Append To = AssignCompletely different. Append/Append To creates a relationship. Assign changes the owner.Append is about relationships. Assign is about ownership.
Wrong access level on Append ToIf Append To on Account is “User” level but the Account is owned by a colleague, you can’t link even with Append on ContactMatch the access level to cover the parent record you’re linking to

Access Levels (Scope) — How Far Your Privilege Reaches

Access levels define the scope of a privilege. Having “Read” on Contacts determines which contacts you can read — not just that you can.

ACCESS LEVEL SCOPE — FROM NARROWEST TO BROADEST
None
No access
User
Own records only
Business Unit
Anyone in same BU
Parent:Child BU
BU + all child BUs
Organization
All records, all BUs
broader scope →

Access Level Decision Matrix:

ScenarioRecommended LevelReason
Sales rep should only see their own accountsUserRestricts to self-owned records only
Sales manager sees all accounts for their teamBusiness UnitCovers all users in the same BU
Regional VP sees EMEA + all country sub-BUsParent:Child BUIncludes parent BU and all child BUs
Global admin sees all accounts worldwideOrganizationNo BU restriction
Prevent a role from deleting contactsNoneExplicitly block the privilege

Important Note: Access levels only apply to user-or-team owned tables. For organization-owned tables (like Currency, Language, Unit of Measure Group), the only options are full access or no access — the BU hierarchy is irrelevant for these.


The Assign Privilege — Transferring Record Ownership

Assign lets a user transfer ownership of a record to a different user or team. It is entirely separate from Append/Append To:

  • Assign → changes who owns the record
  • Append / Append To → creates a relationship between two records

Walkthrough — Alice reassigns Opportunity #101 from Bob to Charlie:

All three are in Sales BU. Alice has Business Unit-level Assign on Opportunity.

  1. Alice has Business Unit Read → she can see Bob’s Opportunity ✅
  2. Alice has Business Unit Assign → she can reassign it ✅
  3. Owner changes: Bob → Charlie. Bob can no longer see it (User-level Read = own records only). Charlie can now see it (he now owns it).
  4. What if Charlie is in Support BU? The record’s owning BU changes to Support BU. Sales BU users with only Business Unit Read now lose access to that record.

Important Note — Cross-BU Assignment: Assigning to a user in a different BU changes the record’s owning BU, potentially removing access from the original BU’s users. Enable “Allow record ownership across BUs” to prevent this side effect.

Assign to a User vs a Team:

TargetEffectWho Gets Access?
Assign to UserOwner becomes that individual user; owning BU = user’s BUOnly that user (and those with Parent-Child/Org access)
Assign to Owner TeamOwner becomes the team; owning BU = team’s BUAll current AND future members of that team

Assign privilege scope:

Access LevelCan Reassign Records Owned By…
NoneCannot reassign any records
UserOnly records they themselves own
Business UnitAny record owned by anyone in their BU
Parent:Child BURecords in their BU and all child BUs
OrganizationAny record in the entire environment

Predefined / Built-in Roles Reference

Dataverse ships with built-in roles you cannot delete (but can copy as templates). Know these well.

Role NameKey CapabilitiesCannotWho Needs It
System AdministratorFull control — all data, all tables, create/modify security roles, manage BUs, users, teamsNothing — most powerful rolePlatform admins only. Treat like root access.
System CustomizerCustomize the data model (tables, columns, forms, views, apps). Org-level on customization entities.Cannot read all data (User-level on most tables). Cannot manage security roles.Makers/devs who need to customize but not access all data
Basic UserUse model-driven apps. Read own records.Cannot create apps, flows, or customizationsEvery end-user needs this as a baseline
Environment MakerCreate Power Apps, Power Automate flows, custom connectors, AI modelsCannot access any Dataverse data (no table read privileges)Citizen developers / makers
DelegateAct on behalf of another user (impersonation via API)Cannot do anything without additional rolesService accounts / integrations needing impersonation

Important Note — System Customizer vs System Administrator:

  • Need to build a custom table and canvas app, but not see business data? → System Customizer + Environment Maker. The customizer role gives org-level access to customization entities but only user-level access on data tables.
  • Need to create a canvas app that reads Dataverse data? → Environment Maker (to build the app) + Basic User (to read data) + appropriate table privileges for the specific tables the app reads.

Field (Column) Security Profiles

Even if a user can read a record, you can hide or restrict individual columns using Field Security Profiles — the sixth and most granular security layer.

How it works:

  1. Mark a column as Field Security Enabled in table/column settings
  2. Create a Column Security Profile granting Read, Create, or Update access to that field
  3. Assign the profile to specific users or teams
  4. Only users with the profile can see/edit that field — everyone else sees a masked or empty value
FIELD SECURITY PROFILE — SALARY COLUMN EXAMPLE
R = Read · W = Write/Update · C = Create
👤 Regular Employee
No Field Security Profile assigned
Full Name
RWC
Department
RWC
💰 Annual Salary
Email
RWC
👔 HR Manager
”HR-SalaryProfile” assigned (Read + Write)
Full Name
RWC
Department
RWC
💰 Annual Salary
RW
Email
RWC

HR Manager can read and update the salary field, but the Create column is blocked (—) — they can’t set the salary when first creating a new record.

Field Security rules:

RuleDetail
System Administrator bypassSys Admins always see all fields, regardless of profiles
Record access is separateFSP requires the user to already have record-level access via security role — it doesn’t grant record access
Default: lockedWhen you enable field security on a column, no one (except Sys Admin) can read/write it until you assign a profile
Performance overheadUse sparingly — too many secured fields adds query overhead

Hierarchical Security

Hierarchical security allows managers to access data of their direct and indirect reports, based on the org chart — independent of Business Units.

Manager Hierarchy uses the “Manager” field on the User record. A manager can read (and optionally write) records owned by their reports, up to a configurable depth. Works across BUs.

Position Hierarchy uses a custom Position table. More flexible — you build org chart structures independent of the Manager field.

MANAGER HIERARCHY — WHO CAN SEE WHAT
👔 VP Sales (Jane)
Sees ALL records below
Manager (Alice)
Sees Bob + Charlie
Rep (Bob)
Own records only
Rep (Charlie)
Own records only
Manager (Dave)
Sees Eve
Rep (Eve)
Own records only
Jane sees records from all 5 people · Alice sees Bob + Charlie · Dave sees Eve

Important Note: Hierarchical security is read-only by default for managers looking at subordinate data. You can enable write access, but managers seeing their reports’ records without being able to edit them is the default and most common configuration.


Record Sharing

Sharing gives a user or team access to a specific record without changing ownership. It’s the most surgical, least permanent access mechanism in Dataverse.

Assign 🔄Share 🤝
OwnershipChanges permanentlyStays with original owner
Old ownerLoses ownershipKeeps ownership
BU contextRecord moves to new owner’s BURecord stays in original owner’s BU
ReversibilityRequires re-assigningCan be revoked (unshared) at any time

When sharing a record, you choose which privileges the recipient gets for that specific record: Read, Write, Delete, Append, Assign, Share.

Important Note: You can only share privileges you yourself have on the record. Sharing with a team shares with all current and future members of that team.

Sharing methods compared:

MethodHowBest For
Manual sharingOpen record → Share button → add user/team + permissionsAd-hoc, one-off scenarios
Access team templateDefine template on table → add users to access team for specific recordsRepeatable patterns (e.g., always share Opportunity with Legal for review)
Power Automate flowUse “Grant Access” Dataverse actionAutomated sharing based on business logic

Quick Reference — Privilege Cheat Sheet

PRIVILEGE QUICK REFERENCE
APPEND
Lives on the CHILD table
The record being linked / moved
”I am going somewhere”
e.g. Note, Contact, Task, Line Item
APPEND TO
Lives on the PARENT table
The record receiving the link
”Things come to me”
e.g. Account, Case, Opportunity
🧩 You ALWAYS need both. One without the other = broken relationship.

Optional: Hands-On Practice Labs

If you have access to a Power Apps Developer environment at make.powerapps.com (free), these exercises will solidify everything above.

Lab 1 — Multi-BU Security Structure

Goal: Create a Sales BU with a child EMEA BU and verify data isolation between them.

  1. Power Platform Admin Center → Settings → Business Units → New → create “Contoso Sales” BU (parent: Root), then “EMEA Sales” (parent: Contoso Sales)
  2. Assign one test user to each BU
  3. Create role “Test Sales Role” with Business Unit-level Read/Write/Create on Contact; assign to the Contoso Sales user
  4. Log in as User 1 (Contoso Sales), create a Contact. Log in as User 2 (EMEA Sales) with User-level Read → confirm they cannot see it
  5. Give User 2 “Parent:Child BU” Read → log in again → confirm they can now see it

Lab 2 — Test the Assign Privilege

Goal: Confirm that the Assign privilege allows ownership transfer, and observe what happens when it’s missing.

  1. Role A “Sales Rep” — User-level Read, Write, Create on Contact. No Assign.
  2. Role B “Sales Lead” — Business Unit-level Read + Business Unit-level Assign on Contact.
  3. Log in as Role A user, create a Contact, try clicking “Assign” → button should be hidden or greyed out
  4. Log in as Role B user, find that Contact, assign it to a third user → success
  5. Log back in as the Role A user → confirm the Contact is now invisible (no longer their record)

Lab 3 — Append vs Append To in Action

Goal: Directly experience what happens when Append / Append To are missing.

  1. Create a role with Read, Write, Create on both Contact and Account. Remove Append from Contact and Append To from Account.
  2. Try setting the “Account Name” lookup on a Contact → observe the save error
  3. Add back only Append on Contact → try again → still fails (Append To still missing on Account)
  4. Add Append To on Account → try again → link saves successfully

Lab 4 — Access Team Template in Practice

Goal: Configure an access team template on Opportunity, wire it to the form, and verify the per-record scope works correctly.

  1. In make.powerapps.com → Tables → Opportunity → Properties → Advanced options → toggle on Access Teams → Save
  2. In Power Platform Admin Center → Settings → Templates → Access Team Templates → New → name it “Deal Review”, set table to Opportunity, add Read + Write privileges → Save
  3. Open the Opportunity main form in the form editor → add a subgrid for the “Deal Review” access team template → publish the form
  4. Log in as User A (who owns an Opportunity), open the record, add User B via the Deal Review subgrid
  5. Log in as User B → confirm they can see and edit that one Opportunity
  6. Navigate to the Opportunities list as User B → confirm no other Opportunities are visible
  7. Log back in as User A, remove User B from the subgrid → log in as User B again → confirm access is gone

Further Reading

Comments