Skip to content

Glossary

Delegated Permissions

By Emil Björk · Microsoft ecosystem consultant, Gothenburg

OAuth permissions where an app acts on behalf of a signed-in user, inheriting that user's access rights.

Delegated permissions in Microsoft Entra ID are OAuth permission scopes where an application acts on behalf of a signed-in user. The access token reflects both the app's identity and the user's, and the app can only do what the user can do (further constrained by the granted scopes). Contrast with application permissions, where the app acts on its own with no user context. Delegated is the right model for user-facing apps (web apps, mobile apps, SPAs); application permissions are right for backend services. Many Graph permissions exist in both flavours — Mail.Read (delegated) reads the signed-in user's mail; Mail.Read (application) reads every mailbox in the tenant.

Worked example

A calendar-scheduling add-in registered in Entra ID requests the delegated scope Calendars.ReadWrite. When Alice signs in and uses the add-in, it can read and modify Alice's own calendar — nothing more. If Alice happens to be a manager with delegated access to a colleague's calendar in Outlook itself, the add-in inherits that same delegated access too, because the token reflects what Alice, specifically, is allowed to do. The add-in never gains the ability to touch a calendar belonging to someone Alice has no relationship with, because delegated permissions are always capped by the signed-in user's own rights, not just the scope name.

Common pitfalls

Assuming a delegated scope like Mail.Read behaves the same regardless of who signs in is a common misunderstanding — the actual access an app gets varies user by user, since it's always bounded by what that specific signed-in user could already do. Granting admin consent for a delegated permission that "sounds read-only" without checking whether it also requires the user's own elevated rights (a Directory.Read.All delegated scope, for instance, still needs the signed-in user to have relevant Entra ID role rights to see everything) can lead to surprising gaps in what the app can actually retrieve. And building a backend, unattended job around delegated permissions is a structural mismatch — delegated permissions need an interactively signed-in user in the loop, which doesn't exist in a scheduled task; that scenario calls for application permissions instead.