Impersonation in Dataverse plug-ins
How impersonation works in Dataverse plug-ins — running as the calling user vs system user, the SDK patterns, and the security implications.
By default, a Dataverse plug-in runs with the privileges of the user who triggered the operation. Sometimes the plug-in needs different privileges — to access data the calling user can't see, to update records they couldn't update, or to assume a specific role. Impersonation is the mechanism. Used carefully, it's powerful; used carelessly, it's a security hole.
The default behaviour. Without impersonation:
- Plug-in runs as the calling user.
- Plug-in's data access respects user's security roles.
- Plug-in can do anything the user could do — no more, no less.
This is the safe default; honour user permissions.
The system user. Inside a plug-in:
context.UserId— the calling user.context.InitiatingUserId— same in most cases.IOrganizationServiceFactory.CreateOrganizationService(null)— creates a service running as system user (super-privileged).
The system user can do anything; respects no security roles.
Common reasons to use system user.
- Cross-team operations — plug-in needs to read records from other teams.
- Cascade updates — plug-in updates related records the user doesn't own.
- Audit logging — log to an audit table the user can't write.
- Integration scenarios — service-to-service operations.
The risk. When plug-in runs as system:
- User's privilege boundaries bypassed.
- User can indirectly do things they couldn't directly.
- Data exposure if return values include unauthorised data.
The mitigation: validate user authorisation explicitly within the plug-in, then perform privileged operations.
Specific user impersonation. Instead of system user, impersonate a specific user:
var service = serviceFactory.CreateOrganizationService(specificUserId);
Operations run as that user, respecting their security roles.
Use case for specific impersonation. A workflow that creates records on behalf of a specific group account:
- Multiple users invoke the workflow.
- All resulting records should be owned by a service account.
- Impersonate the service account.
This gives consistent ownership without elevating to system.
Pattern: validate then elevate.
// 1. Validate user authorisation explicitly.
if (!UserCanPerformOperation(callingUser, recordId))
{
throw new InvalidPluginExecutionException("Not authorised");
}
// 2. Elevate to system for actual operation.
var systemService = serviceFactory.CreateOrganizationService(null);
systemService.Update(record);
This pattern keeps user authorisation strict while accomplishing the work that requires elevation.
Recursion considerations. When impersonating, plug-ins on the resulting operations may run differently:
- A plug-in fires on the record update.
- That plug-in sees the impersonated context, not the original user.
- Cascade behaviour can be unexpected.
Document and test carefully.
Audit trail. Operations performed via impersonation:
- The audit trail shows the impersonating identity.
- May or may not preserve the original user information.
- For accountability, log the original user separately within plug-in trace.
Workflow steps and impersonation. Workflow steps have their own context:
- Run as owner — the workflow record's owner.
- Run as user who triggered.
Choose based on whether elevated access is needed.
Power Automate impersonation. Flows have similar concepts:
- Connection identity — typically the user who created the connection.
- Run-only users — for shared flows.
- Service principal connections — bypass user identity.
Each pattern has security implications.
Cross-tenant impersonation. Not natively supported; cross-tenant requires specific setup (B2B users, multi-tenant apps).
Common pitfalls.
- Default to system user. Unnecessarily elevates; security risk.
- No authorisation check. Impersonation bypasses user permissions; user effectively elevated.
- Audit trail unclear. Can't tell who actually did what.
- Performance impact. Creating separate service instances has overhead.
- Cascade effects. Downstream plug-ins see different context than expected.
Best practices.
- Use default user context where possible. Impersonate only when needed.
- Validate explicitly when impersonating. Don't assume permission.
- Log the original user. Even if technical operation is as system, log who initiated.
- Document the impersonation rationale. Why this plug-in needs elevated access.
- Code review for impersonation. Treat impersonation as security-sensitive code.
Comparison with simpler patterns.
- Sharing record — give specific user/team access; user keeps their identity.
- Field-level security — control which columns user sees.
- Hierarchical security — manager sees direct reports.
Sometimes these solve the problem without needing impersonation.
Compliance considerations.
- SOX — segregation of duties; impersonation may breach.
- GDPR — accountability for who accessed personal data.
- Internal audit — review plug-ins using impersonation.
Strategic positioning. Impersonation is a power-tool. Use sparingly, with clear rationale, with explicit authorisation logic, with thorough audit. Plug-ins that lazily run as system because "it's easier" accumulate security debt. The discipline to do impersonation right is a sign of security-conscious engineering; the absence of that discipline is a sign of accidental privilege escalation. For security-sensitive Dataverse deployments, periodic review of plug-in impersonation usage is essential.
Related guides
- Async jobs in DataverseHow Dataverse runs background work — system jobs, async plug-ins, workflow runs, and how to monitor, troubleshoot, and prevent the async backlog from getting out of hand.
- Bulk delete jobs in DataverseHow Dataverse's bulk delete handles mass record cleanup — scheduling, filters, retention policies, and the operational discipline around storage management.
- Business rules in DataverseHow business rules let you add field-level logic to forms without code — set value, lock field, show error, recommendation, and the limits of the engine.
- Business units and teams in Dataverse — a deep diveHow business units, owner teams, access teams, and Microsoft 365 group teams compose the security model in Dataverse — what each is for, how they interact, and the common design mistakes.
- Calculated and rollup columns in DataverseHow calculated columns and rollup columns work in Dataverse — what each does, the performance trade-offs, and when to use a formula column or a Power Automate flow instead.