Impersonation in Dataverse plug-ins

By Emil Björk · Microsoft business apps consultant, Gothenburg

How impersonation works in Dataverse plug-ins — running as the calling user vs system user, the SDK patterns, and the security implications.

Reviewed May 20263 min read · 656 wordsPublished
On this page (11)

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

Browse every guide in Customer Engagement or just Dataverse platform.

Was this helpful?

Signals which guides land and which need work. No account, no comment box — corrections go through the contact page.

Spot something wrong or want a topic covered? Send a correction or a topic request — both are welcome.