Azure permissions explained
Every OAuth scope Permafrost requests from your Azure tenant — what each one reads, what feature it enables, and why nothing broader is needed.
The read-only guarantee
Permafrost's service principal is granted read-only application permissions during admin consent. The product never creates, modifies, or deletes objects in your tenant during background sync. The only exception is Mode C remediation — an explicit, user-initiated action where you choose to apply a specific recommendation through your own browser session.
A subset of permissions is granted immediately at first consent (V1 Core + Azure Resources). Remaining permissions are added progressively when you enable each cloud surface — your tenant is never granted more access than your current feature configuration requires.
Core identity (V1 — always required)
These six permissions are requested at initial consent. They are the minimum needed to discover identities, role assignments, and the activity evidence that powers UPRS scoring.
| Permission | What it reads | Why it's needed |
|---|---|---|
Directory.Read.All | Users, groups, service principals, managed identities, agent identities, app registrations | The primary identity inventory. Every finding, role recommendation, and permission score starts here. |
RoleManagement.Read.Directory | Azure AD directory role definitions and assignments (Global Admin, Privileged Role Admin, etc.) | Required to identify which identities hold Tier-0 directory roles. Without this, critical findings like tier0_permanent_root cannot fire. |
AuditLog.Read.All | Sign-in activity for users and service principals | Used to determine when an identity last signed in (the dormancy signal). Also reads SP sign-in activity via the beta signInActivity property. |
Application.Read.All | App registrations and enterprise applications | Required to read service principal credentials (client secrets and certificates) for the SP credential analysis surface. |
GroupMember.Read.All | Group memberships (direct and transitive) | Groups are containers for role assignments. Transitive group membership determines effective inherited access. Also resolves M365 group owners for Teams and Viva Engage community admin analysis. |
Policy.Read.All | Conditional Access policies, named locations, and authentication policies | Powers the CA posture simulator (/dashboard/conditional-access): which identities are gated by MFA, which are in break-glass exclusion lists. |
Azure resources (V2 — always required)
Azure Resource Manager access is required to enumerate ARM RBAC role assignments across your subscriptions, resource groups, and individual resources. This is the primary source for the permission-usage surface and the ARM scope hierarchy view.
| Permission | What it reads | Why it's needed |
|---|---|---|
Azure Resource Manager — user_impersonation (delegated) | ARM RBAC role assignments, role definitions, subscriptions, resource groups, management groups | Background sync uses client_credentials against https://management.azure.com/.default — not impersonating any specific user. The delegated scope is also used for Mode C remediation (user-initiated session only). |
Privileged Identity Management (V3/V4)
Added when a tenant is on consent version 3 or higher. These scopes are required to read PIM-managed assignments — Policy.Read.All covers standard CA policies but does NOT grant access to PIM scheduling or policy endpoints despite the naming overlap.
| Permission | What it reads | Why it's needed |
|---|---|---|
RoleAssignmentSchedule.Read.Directory | Active PIM role assignment schedules (time-bounded active assignments) | Distinguishes active PIM assignments from permanent ones. Feeds the tier0_permanent_root and permanent_assignment_should_be_eligible findings. |
RoleEligibilitySchedule.Read.Directory | PIM eligible role assignments | Required to identify which identities are eligible for roles without holding them permanently — the foundation of the PIM eligibility analysis. |
RoleManagementPolicy.Read.Directory | PIM activation policy rules: MFA requirement, approval requirement, maximum activation duration, notification settings | Powers findings like weak_activation_policy_tier0 and eligible_with_no_mfa_requirement. Policy.Read.All does not cover this namespace. |
Conditional Access (V5)
| Permission | What it reads | Why it's needed |
|---|---|---|
AuthenticationContext.Read.All | CA authentication context class references (/identity/conditionalAccess/authenticationContextClassReferences) | Needed to detect the auth_context_referenced_but_undefined finding — CA policies that reference auth contexts not enforced anywhere. Policy.Read.All does not cover this endpoint. |
Intune (V6)
| Permission | What it reads | Why it's needed |
|---|---|---|
DeviceManagementRBAC.Read.All | Intune RBAC role definitions, role assignments, and scope tags (/deviceManagement/roleDefinitions, /deviceManagement/roleAssignments) | Powers the Intune surface (/dashboard/intune). DeviceManagementApps.Read.All and DeviceManagementConfiguration.Read.All are NOT requested — they are broader than needed. |
Exchange Online (V7)
Exchange Online exposes two separate API surfaces, each requiring a distinct permission. Both are enabled by the Step-2 binding documented at /dashboard/exchange/setup.
| Permission | What it reads | Why it's needed |
|---|---|---|
RoleManagement.Read.Exchange | Exchange RBAC role definitions and assignments via Microsoft Graph beta (/beta/roleManagement/exchange/...) | Reads the Exchange Online unified role model where Microsoft has started migrating RBAC to Graph. |
Exchange.ManageAsApp (Office 365 Exchange Online app role) | Exchange Online PowerShell REST API (GET operations only): Get-RoleGroup, Get-RoleGroupMember, Get-ManagementRoleAssignment, Get-ManagementScope | Microsoft provides no read-only equivalent for app-only EXO PowerShell authentication. Despite the "Manage" name, only Get-* cmdlets are called — no Set-*, New-*, or Remove-* commands appear anywhere in the codebase. This is verified in src/lib/sync/exchange.ts. |
Exchange.ReadAsAppor equivalent read-only app role for Exchange Online PowerShell. Application-level PowerShell authentication requires this role. Permafrost's code calls only Get-* cmdlets — a restriction enforced in code review and verified in the permission audit (PERMISSIONS.md in the repository).Microsoft Purview (V8)
Requires a Step-2 binding: the Permafrost service principal must be assigned a Purview eDiscovery role-group membership by your administrator (documented at /dashboard/purview/setup). Tenants without Purview eDiscovery (Premium) licensing receive a 401 and the surface shows a licensing notice, not an error.
| Permission | What it reads | Why it's needed |
|---|---|---|
eDiscovery.Read.All | Purview eDiscovery cases (/security/cases/ediscoveryCases) and case memberships | Identifies which identities hold eDiscovery Manager or eDiscovery Administrator roles — high-privilege roles that grant access to all mailboxes in scope. |
Microsoft Defender (V9)
| Permission | What it reads | Why it's needed |
|---|---|---|
RoleManagement.Read.Defender | Defender unified RBAC role definitions and assignments (/beta/roleManagement/defender/...) | Powers the Defender surface (/dashboard/defender). Tenants that have not activated Defender unified RBAC return an empty list — no error. |
Microsoft Teams (V11)
| Permission | What it reads | Why it's needed |
|---|---|---|
Team.ReadBasic.All | Teams list and basic team properties (/v1.0/teams) | Required to enumerate Teams and identify owner / membership patterns. Per-team channel content and meeting data are never requested. |
Viva Engage (V13)
| Permission | What it reads | Why it's needed |
|---|---|---|
Community.Read.All | Viva Engage native-mode community inventory (/v1.0/employeeExperience/communities) | Required to discover communities and identify those backed by groups with guest owners — the viva_engage_community_with_guest_owner finding. |
EngagementRole.Read.All | Tenant-wide Viva Engage engagement role memberships: Network Admin, Verified Admin, Corporate Communicator | These roles have tenant-wide administrative power in Viva Engage. Conversation, message, and export scopes are explicitly NOT requested. |
Agent Identities (V15)
Microsoft Entra agent identities are a new principal type introduced with Microsoft 365 Copilot and autonomous agents. These three permissions provide read access to the agent identity namespace.
| Permission | What it reads | Why it's needed |
|---|---|---|
AgentIdentity.Read.All | Microsoft Entra agent identity directory objects (/v1.0/servicePrincipals/microsoft.graph.agentIdentity) | Agent identities (ServicePrincipalType = ServiceIdentity) are a new privilege-bearing principal type that CIEM must track. |
AgentIdentityBlueprint.Read.All | Agent identity blueprints and their sponsor relationships | Blueprints define which agents can be instantiated and by whom. Sponsors are the identities authorised to deploy agents from a blueprint. |
AgentIdentityBlueprintPrincipal.Read.All | Blueprint principal authorizations — service principals authorised to instantiate agents from blueprints | Identifies which SPs can create agent instances. A high-privilege SP authorised to instantiate agents is a significant blast-radius signal. |
Permissions we deliberately do not request
The following categories of permissions were evaluated and rejected:
- Any write application permission — no
*.Write.*,*.ReadWrite.*, or similar scopes appear in the manifest. - Conversation / message content — EngagementConversation.Read.All, EngagementExport.Read.All, and Teams message scopes are out of CIEM scope. Message bodies are a DLP/eDiscovery concern, not an entitlements concern.
- Tenant.Read.All (Power BI) — Microsoft documents that granting this scope breaks the Power BI admin API authentication contract.
- Non-Microsoft cloud permissions — AWS, GCP, and OCI are outside Permafrost's scope. Only Microsoft Azure and Entra ID are analysed.
- File and document content — SharePoint document libraries, OneDrive file contents, Exchange mailbox content. Permafrost analyses entitlements, not content.
How to review or revoke consent
You can review, modify, or fully revoke Permafrost's consent from the Azure Portal at any time:
- Open Azure Portal → Microsoft Entra ID → Enterprise Applications.
- Search for Permafrost EPM (or your app registration name).
- Select Permissions to review all granted scopes.
- To revoke: select Revoke admin consent. This immediately disconnects Permafrost from your tenant. Existing data in Permafrost is preserved until you disconnect the tenant from Settings.