Repository navigation
Runtime Permissions
Prerequisites → Runtime Permissions
The runtime account needs two kinds of access, both described below:
- Microsoft Graph & Microsoft 365 API permissions — to read Microsoft 365 data (consented by an Azure AD administrator).
- Azure RBAC roles — data-plane access to the Azure resources the solution deploys (assigned automatically by the installer).
Note: the solution can run without some of the API permissions if an incomplete dataset is acceptable. Where access isn't granted, it logs an error and continues working.
Important: without an Azure AD administrator's consent, these permissions will not be active.
| API | Permission | Reason |
|---|---|---|
| Graph | AppCatalog.Read.All |
Not used by current builds: nothing in the code reads the Teams app catalog. The Teams import reads each channel's tabs, including the Teams app behind each tab, with Group.Read.All, which Microsoft documents as sufficient for listing a channel's tabs, and the installer's checks don't ask for this permission. Don't grant it for a new installation. If an existing one holds it, run a Teams import without it in a test tenant before you revoke it. |
| Graph | CallRecords.Read.All | Reading call-record data after calls are made. |
| Graph | CopilotPackages.Read.All |
(Optional.) Reading the Microsoft Agent 365 Package Management API catalog. Required only when Agent365PackageCatalog is enabled. Requires a Microsoft Agent 365 license, admin consent, and the global cloud. See Agent 365 package catalog. |
| Graph | Group.Read.All | Enumerating Teams data and reading direct members of UserGroupsFilter groups; both WebJobs need it when that filter is used. Also covers the optional leadership group. GroupMember.Read.All suffices for leadership membership alone, not all group reads. See import scoping. |
| Graph | OnlineMeetings.Read.All | Reading Copilot event meeting context. Also needs a Teams application access policy — see Copilot → Meeting enrichment also needs a Teams application access policy. |
| Graph | Organization.Read.All | Reading SKUs for users at an org level. |
| Graph | Reports.Read.All | Reading user and device usage reports, and the three Microsoft 365 Copilot usage reports when GraphCopilotUsageReports is enabled. Global cloud only. A missing or unconsented grant now fails the report import rather than recording an empty day — see Copilot usage reports. |
| Graph | Sites.Read.All | Reading SharePoint file metadata for Copilot file events (via /sites/{id}/lists/{listId}/items). |
| Graph | AiEnterpriseInteraction.Read.All |
(Optional, and not granted by the installer.) Reading Microsoft 365 Copilot AI interaction history, i.e. prompt history. Required only when CopilotInteractionHistory is enabled. This one needs explicit admin consent — see Copilot AI interaction history needs its own consent below. |
| Graph | AuditLogsQuery.Read.All | (Optional, and not granted by the installer.) Searching the Microsoft 365 unified audit log for Copilot interactions older than the live import can reach. Required only to run a Copilot audit backfill (Preview). Needs explicit admin consent. It can read the whole audit log, so you can remove it again once you no longer need the backfill. |
| Graph | Mail.Read | (Optional) Reading the message properties of each in-scope user's Sent Items for the Sent Email Import feature. Required only when SentEmails is enabled in ImportJobSettings. Application Mail.Read can read every mailbox in the tenant, and UserGroupsFilter limits what is processed, not what the app can access. Restrict which mailboxes it can read in Exchange Online: either keep this consent and constrain it with an application access policy, or remove the consent and grant a scoped RBAC for Applications role assignment instead, which Microsoft describes as the replacement for application access policies. An RBAC assignment adds to an Entra consent rather than restricting it, so don't keep both. Test Configuration checks for the Entra consent, so it reports an error on the RBAC-only route; verify the import yourself. Either way, test both an allowed and a denied mailbox. The import scans the mailboxes of users the user import has stored, so it also needs User Entra ID extended metadata (GraphUsersMetadata). See Sent Email Import. |
| Graph | User.Read.All | Resolving user IDs to email addresses. Required for various processes. |
| Office 365 Management | ActivityFeed.Read | Reading audit data for SharePoint Online events, and for Power Platform adoption events (Power Apps, Power Automate, Power BI, Copilot Studio — read from both the legacy PowerApps/MicrosoftFlow workloads and the unified PowerPlatform admin activity feed). See Power Platform auditing prerequisites below — the events will not flow unless Power Platform auditing is enabled per environment. |
| Office 365 Management | ActivityFeed.ReadDlp |
(Optional, and not granted by the installer.) Reading Data Loss Prevention policy events (the DLP.All feed). Required only when ImportDlp is enabled. This is a separate grant from ActivityFeed.Read with its own admin consent. You do not need it for Copilot DLP reporting — see Data Loss Prevention import is optional, and is not what powers Copilot DLP reporting below. |
| Application Insights API | Data.Read | Reading Application Insights data. Only needed for web-traffic imports. |
Directory.Read.Alland Test Configuration. Current builds' Test Configuration reports an error if the runtime app doesn't holdDirectory.Read.Allwhile the user metadata import (GraphUsersMetadata) is on, and the installer's Prerequisites report says the user import "reads other users' directory memberships". That describes an older per-usermemberOfread. The current import doesn't use the permission: it reads people withUser.Read.Alland, only whenUserGroupsFilteris set, the groups' direct members withGroup.Read.All. Whether to grant the broader permission just to clear that one test result is your decision.If the runtime app can't read the
UserGroupsFiltergroups, the imports fail open: they keep the membership they last resolved, or import everyone if none has been resolved since the WebJob started. See Security model → Data privacy.
No longer required:
TeamsAppInstallation.ReadForUser.All. It existed for per-user Teams app-install tracking, which was removed in Stable build 1807. If it is still granted you can revoke it; nothing reads it any more. See Data Collection → Per-user Teams apps tracking (removed).
The CopilotInteractionHistory import is deliberately harder to turn on than the others, and there are three separate prerequisites — all of them must be in place or the import does nothing:
-
AiEnterpriseInteraction.Read.All, admin-consented. The installer does not request or grant this permission. An Entra administrator has to add it to the runtime app registration and grant admin consent explicitly. Without it the import fails rather than silently recording an empty run. -
The
M365_COPILOT_BUSINESS_CHATservice plan on each user. Users without it return nothing. -
A scope, in practice. The Graph endpoint (
/copilot/users/{id}/interactionHistory/getAllEnterpriseInteractions) is one HTTP call per user. At the ~200,000-user design target an unscoped run would mean 200,000 Graph calls per import cycle. Point it at a pilot group withUserGroupsFilter; the import is also capped per cycle as a backstop.
Privacy — read before enabling. The importer never stores prompt or response text; it stores derived statistics (word counts, attachment counts, response latency and similar). However, if Cognitive Services is also configured, prompt text is sent to Azure AI Language so that language, sentiment and keywords can be extracted and stored. Extracted keywords can amount to a whole short prompt. That is a new egress path for prompt content out of your tenant and should be a conscious, documented decision — see Security Model → Copilot prompt content.
(Optional) If you need to access Yammer data, the setup needed is explained in /export · Yammer Developer Site.
The ImportDlp toggle and its ActivityFeed.ReadDlp permission are entirely optional. The solution installs, runs and reports perfectly well without them, and the installer neither requests nor grants the permission.
The single most important point: the "DLP impact on Copilot" report — which agents and people are being blocked, and by which policies — does not need this permission or this toggle. That data arrives on the Copilot interaction records you are already importing under Copilot.
Why: DLP policies scoped to the "Microsoft 365 Copilot and Copilot Chat" location do not emit records on the DLP.All feed at all. Microsoft documents that feed's workloads as Exchange Online, Endpoint and SharePoint/OneDrive only. A Copilot block is instead reported inside the CopilotInteraction record, on AccessedResources[].Status and AccessedResources[].PolicyDetails, next to AgentId / AgentName — which is also the only reason per-agent attribution is possible at all. See Audit logs for Copilot and AI applications.
So the two DLP sources answer different questions:
Needs ActivityFeed.ReadDlp? |
Enabled by | Answers | |
|---|---|---|---|
| Copilot-embedded DLP | No |
Copilot (already on for Copilot reporting) |
Which agents and people were blocked, and by which policies |
DLP.All feed |
Yes | ImportDlp |
Tenant-wide policy activity across Exchange, SharePoint/OneDrive and endpoint devices |
Turn ImportDlp on only if you want that second, tenant-wide picture. Note it can never be attributed to a Copilot agent: DLP records carry the literal UserKey = "DlpAgent" and no agent identity, so the report shows them in their own section and deliberately does not join them to Copilot activity.
If you enable it without the permission, nothing else breaks. The DLP subscription is treated as optional: the importer logs a warning naming the missing grant, drops that one feed for the cycle, and every other workload imports normally. Once an administrator consents, DLP data starts arriving on the next cycle with no reinstall.
Privacy: the solution deliberately does not request the separate "Read DLP policy events including sensitive details" permission. It records that a policy fired — the policy, rule, severity and action — and never the content that triggered it.
The ActivityFeed.Read permission lets the importer read Power Platform audit events from the Office 365 Management Activity API, but those events only exist if Power Platform auditing is enabled in the tenant. No Power Platform adoption data will appear in reports until a Power Platform / global admin completes the steps below.
- Confirm Microsoft Purview Audit is enabled at the tenant level. Usually on by default, but a tenant admin can verify (and turn it on if necessary) from the Microsoft Purview portal. See Microsoft Purview auditing solutions overview. This single setting is enough for Power BI / Fabric activity events to flow — there is no separate Power BI tenant toggle to enable.
- Configure and turn on auditing for each Power Platform production environment you want to monitor (applies to Power Apps, Power Automate, Copilot Studio and Dataverse). This is the step that's most often missed — adoption events for those workloads only flow for environments where auditing has been explicitly turned on. See Overview of Power Platform activity logging and auditing in Microsoft Purview → Configure and turn on auditing for each Power Platform environment.
Per-workload Microsoft Learn references the importer is built against:
| Workload | Microsoft Learn |
|---|---|
| Power Apps | View Power Apps activity logs in Microsoft Purview |
| Power Automate | View Power Automate activity logs in Microsoft Purview |
| Power BI | Track user activities in Power BI (no separate tenant toggle — uses the Purview audit log) |
| Copilot Studio | Audit Copilot Studio activities in Microsoft Purview |
| Power Platform admin (unified) | Power Platform Administrator Activity (RecordType 256) |
If reports show empty Power Platform tables after deploy, the most likely cause is that auditing is on for the tenant but not for the target Power Apps / Automate / Copilot Studio environment(s). Validate by searching the Microsoft Purview portal audit log for the corresponding activity (e.g. LaunchPowerApp, FlowRunStarted, ViewReport) before suspecting the importer.
Teams delegated permissions apply only to deep Teams analytics and are requested through Connect to Microsoft Teams, not ordinary sign-in. The billing connection is a separate optional delegated Power Platform flow. Choose Delegated, not similarly named application permissions.
Older builds asked for these at every sign-in. Before Stable build 1846, a runtime app registration without consent for them stopped anyone signing in, with
AADSTS65001. See Known Issues.
| API | Permission | Reason |
|---|---|---|
| Graph | ChannelMessage.Read.All | Reading channel messages in the Teams an administrator authorises for deep analytics (see Enable Deep Analytics for Teams). Always needs admin consent. |
| Graph | Team.ReadBasic.All | Listing the administrator's own Teams on the Teams permissions page. |
| Power Platform API | CopilotStudio.Licenses.Read; EnvironmentManagement.Environments.Read |
Consumption connection only. Add/grant delegated consent on the runtime registration, use the same authorised administrator, register the exact Web /signin-agent-costs callback and provide durable Storage/Table access. See Agent costs setup. |
Beyond the API permissions above, the runtime service principal needs data-plane access to the Azure resources the solution deploys (so it can read/write storage, call Azure AI Language, and send/receive Teams-call messages). The installer assigns these Azure RBAC roles automatically when you install or re-run it. Since Stable 1859 (PR #828) it assigns each data-plane role on the one resource the runtime uses, and only Reader on the resource group, which can hold other workloads; earlier installers assigned every role on the resource group. They are listed here so you can pre-grant, audit, or assign them manually (for example for a binaries-only redeploy, or where policy restricts who may create role assignments).
| Azure RBAC role | Scope | Why | When |
|---|---|---|---|
| Reader | Resource group | Read resource metadata, including Application Insights. | Always |
| Storage Blob Data Contributor | The solution's storage account (the resource group before 1859) | Create containers and read/write blobs. | Always |
| Storage Table Data Contributor | The solution's storage account (the resource group before 1859) | Read/write the AnalyticsState table for runtime state and table-based checkpoints when shared-key storage access is disabled. |
Always |
| Cognitive Services User | The Azure AI Language account (the resource group before 1859) | Data-plane calls to Azure AI Language (sentiment / key-phrase) when key auth is disabled. | If Cognitive Services is enabled |
| Cognitive Services OpenAI User | The Azure OpenAI account (the resource group before 1859) | Inference for the optional prompt-categorisation backend's runtime Entra credential, not permission to send prompts | Installer-managed Foundry service enabled; assign manually for an approved existing deployment |
| Azure Service Bus Data Owner | The Teams calls queue, graphcalls (the resource group before 1859) |
Send (calls webhook) and receive (importer) on the Teams-calls queue via Entra ID RBAC instead of a SAS key. Since Stable 1856 (PR #768): the importer also sends, to re-queue a failed call for a later retry, which this role already allows. | If Service Bus (Teams calls) is enabled |
Service Bus: if your namespace has local (SAS) authentication disabled, the importer authenticates with Entra ID RBAC and requires the Azure Service Bus Data Owner role above. Re-running the installer assigns it; for a binaries-only redeploy, assign it once manually or the calls processor will return
401 Unauthorized.
Upgrading from a build before 1859: a re-run adds the resource-scoped assignments, but doesn't remove the older ones on the resource group, because nothing records whether the installer or an administrator made them. Each run logs a warning for each one it finds, with the
az role assignment delete --ids <assignment-id>command that removes it. Once the solution has run normally on the narrower assignments, remove them with that command, or in the resource group's Access control (IAM). Role changes can take a few minutes to apply.
Key Vault: the runtime app and the App Service's managed identity can read the runtime secret and certificate. The installer grants this with a vault access policy (runtime app: secrets Get/List and certificates Get; managed identity: secrets Get and certificates Get) or, on a vault that uses the Azure RBAC permission model, with Key Vault Secrets User and Key Vault Certificate User at vault scope. The installer's own app gets permission to write the secret: Key Vault Secrets Officer on an RBAC-model vault. The installer adds all of this automatically; see Security model → Secrets & Key Vault.
The optional agent-cost imports need two grants the installer deliberately does NOT make. Both are tenant-wide or subscription-wide privilege grants, so they are left to an administrator who can make that decision:
Import Grant needed Scope Who can grant it Copilot Studio capacity Power Platform Reader for the runtime enterprise application Tenant Power Platform Administrator Copilot Studio consumption Delegated Power Platform consent and connected administrator with billing access; no app-only fallback Shared deployment connection Entra consent administrator and authorised billing/portal administrator Azure costs ( AzureCostManagement)Cost Management Reader Every scope you want to read Owner / User Access Administrator on that scope, or a billing admin for EA/MCA The Azure import additionally does nothing until you set the
AzureCostScopesapp setting — it has no default. Without these, ticking the boxes produces authorization failures or an empty report rather than data. Full setup: Agent costs.
- Copilot analytics overview
- Copilot Adoption user guide
- Copilot Adoption setup (admins)
- Work Trend Index
- Copilot investment
- Copilot spend
- Agent costs
- Prompt categories
- Copilot credit history (preview)
- Agent 365 package catalog
- The Copilot data in depth
- Prerequisites
- App registrations setup
- Install with the installer
- Verify the deployment
- Security & permissions model
- Private endpoints (optional)
- Certificate authentication (optional)
- Manual installation
- Activity & usage analytics (Power BI)
- SharePoint page tracking