---
title: Granting CloudMonitor access to your Azure environment
canonical: "https://cloudmonitor.ai/docs/cloudmonitor-fabric-beta/granting-cloudmonitor-access-to-your-azure-environment/"
description: "Authorize the CloudMonitor multi-tenant service principal and grant read-only access to your subscriptions, billing account, and cost-export storage for the Fabric SaaS beta."
---

import ArchitectureDiagram from '~/components/docs/ArchitectureDiagram.astro';
import DownloadPdfButton from '~/components/DownloadPdfButton.astro';

Thank you for joining the CloudMonitor beta. This guide explains exactly what
you need to do so CloudMonitor can read your cost and usage data and start
producing FinOps insights for your organization.

<DownloadPdfButton />

CloudMonitor connects through a **multi-tenant service principal** that we
provide. You authorize our application, grant it **read-only** access to the
subscriptions and billing scope you choose, and create one dedicated storage
account that receives your scheduled cost exports. Our backend then reads your
cost and usage data from that export and through the Azure APIs.

<ArchitectureDiagram />

:::note[CloudMonitor is read-only and cannot make any changes to your resources]
Every access role below is a *reader* role: CloudMonitor can see service
metadata and costs, but **cannot** change your resources and **cannot** read
the data inside your services — for example, key vault secrets, database
contents, or application blobs.
:::

## What we send you

We send you **one thing: the admin consent URL** (used in Step 1). You don't
need any IDs from us up front.

When you open that URL and approve it, Azure automatically creates the
CloudMonitor application in your tenant. It always has the same fixed
identifiers, so you can recognize and look it up afterwards:

| Identifier | Value |
| --- | --- |
| **Display name** | `cloudmonitor-beta` |
| **Application (client) ID** | `ef7bf83e-23c6-4d84-962b-a3b0f14695a5` |

Use the display name **`cloudmonitor-beta`** (or the client ID above) to find
and select the service principal whenever you assign roles in the steps below —
or any time you want to look it up in Microsoft Entra.

After you finish, you simply let us know — see
[Let us know when you're done](#let-us-know-when-youre-done).

## Before you start — who needs to do this

:::caution[These are roles *your own people* need — not access you give CloudMonitor]
The right-hand column lists the role the person performing each step must
already hold in your own tenant to carry it out. These are not roles or
permissions you hand to CloudMonitor, and you are not giving us any admin
rights. No matter which steps you do, CloudMonitor only ever receives
read-only access — see the [quick reference](#quick-reference--everything-cloudmonitor-asks-for)
for the exact (read-only) roles we end up with.
:::

You will need people who **already hold** the following Azure roles. They can be
the same person or several different people.

| Step / action | Role the person doing it must already hold |
| --- | --- |
| Authorize the CloudMonitor app (Step 1) | **Cloud Application Administrator** (or Global Administrator) |
| Assign the **Reader** role on subscriptions / management groups | **Owner** (or User Access Administrator) on that scope |
| Grant **EA** billing access | EA **Department Administrator** or **Account Owner** |
| Grant **MCA** billing access | **Global Administrator** with billing-account access |
| Create the cost-export storage account and assign its role (Step 4) | **Owner** on the chosen subscription (or **Contributor** + **User Access Administrator**) |

## Step 1 — Authorize the CloudMonitor application

This is a one-time action. It provisions the CloudMonitor service principal in
your tenant so you can assign it the read-only Azure roles in Steps 2 and 3.
CloudMonitor requests **no directory or Microsoft Graph permissions** — all of
its access comes from the Azure role assignments you make below.

1. An administrator opens the **admin consent URL** we provided
   (it looks like
   `https://login.microsoftonline.com/<your-tenant-id>/adminconsent?client_id=ef7bf83e-23c6-4d84-962b-a3b0f14695a5`).
2. Sign in and click **Accept**. Because CloudMonitor requests no directory
   permissions, this simply creates the application in your tenant — it does
   not grant any access on its own.
3. Once complete, a matching entry appears in your tenant under
   **Microsoft Entra ID → Enterprise applications**. You can confirm it by
   searching for the display name **`cloudmonitor-beta`** (or the client ID
   above).

:::tip
If your organization restricts who can register applications, an administrator
with the **Cloud Application Administrator** (or **Global Administrator**) role
will need to complete this step.
:::

## Step 2 — Grant subscription read access

Do this for **each Azure subscription** you want CloudMonitor to monitor. If
you use **management groups**, assign the role once at the management-group
scope and every current and future subscription underneath is covered
automatically — this is the recommended approach.

1. In the [Azure portal](https://portal.azure.com), open the **subscription**
   (or **management group**) you want to monitor.
2. Select **Access control (IAM)**.
3. Click **+ Add → Add role assignment**.
   - If **+ Add** is greyed out, your account does not have the **Owner**
     role on this scope. Ask whoever does to complete this step.
4. On the **Role** tab, select **Reader**, then click **Next**.
5. On the **Members** tab, choose **User, group, or service principal** and
   click **Select members**.
6. Search for **`cloudmonitor-beta`** (or paste the client ID above), select
   it, and click **Select**.
7. Click **Review + assign**.
8. Repeat for any additional subscriptions, or use a management group to cover
   them all at once.

:::note
**Reader** lets CloudMonitor read service-plane metadata and costs only. It
cannot modify resources and cannot read data inside services.
:::

## Step 3 — Grant billing access

Cost data is most complete when CloudMonitor reads it at the **billing
account** scope. The exact steps depend on your **billing agreement type**.

Not sure which you have? See Microsoft's guide:
[Check the type of your billing account](https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/manage-billing-access#check-the-type-of-your-billing-account).

Choose the section that matches your agreement:

- [3a. Microsoft Customer Agreement (MCA)](#3a--microsoft-customer-agreement-mca)
- [3b. Enterprise Agreement (EA, legacy)](#3b--enterprise-agreement-ea-legacy)
- [3c. No billing-account access (or running through a CSP)](#3c--no-billing-account-access-or-running-through-a-csp)

:::note
Only **MCA** and **EA** billing accounts are supported at the billing scope.
Other account types (for example, pay-as-you-go / MOSP or credit accounts)
should use the [subscription-scope fallback](#3c--no-billing-account-access-or-running-through-a-csp).
:::

### 3a — Microsoft Customer Agreement (MCA)

A **Global Administrator** with billing access grants the read-only
**Billing account reader** role to the CloudMonitor app.

1. In the Azure portal, open **Cost Management + Billing**.
   *(This is at the billing-account level, not the subscription level.)*
2. Select the **billing scope** (billing account or billing profile) you want
   CloudMonitor to read.
3. Select **Access control (IAM)** and click **+ Add**.
4. Choose the **Billing account reader** role. *(This role has no write
   permissions.)*
5. Select the CloudMonitor application and click **Add**.

:::caution[Known Microsoft limitation on MCA]
Microsoft currently restricts some service principals from reading cost data on
certain MCA billing accounts. If our team confirms CloudMonitor isn't receiving
your MCA cost data after this step, we will fall back to the
[subscription-scope method](#3c--no-billing-account-access-or-running-through-a-csp),
which works reliably. We'll guide you if that's needed — no action required
from you up front.
:::

### 3b — Enterprise Agreement (EA, legacy)

EA billing roles can't be assigned in the Azure portal, so this uses the Azure
Billing REST API. It must be run by an EA **Department Administrator** or
**Account Owner**. (If you don't hold one of these roles, ask your Enterprise
Administrator to assign one to you.)

1. Open the REST API "Try it" page:
   [Billing Role Assignments — Put](https://learn.microsoft.com/en-us/rest/api/billing/2019-10-01-preview/role-assignments/put?tabs=HTTP#code-try-0).
   - Sign in with an admin account.
   - Select the AD tenant that you authorized in Step 1.
2. Fill in the **parameters**:
   - **`billingAccountName`** — your **Billing account ID**, found on the
     **Cost Management + Billing** overview page.
   - **`billingRoleAssignmentName`** — a new, unique GUID. Generate one at
     [guidgenerator.com](https://guidgenerator.com).
3. Paste this into the **Body**, replacing the placeholders:

   ```json
   {
     "properties": {
       "principalId": "<cloudmonitor-service-principal-object-id>",
       "principalTenantId": "<your-tenant-id>",
       "roleDefinitionId": "/providers/Microsoft.Billing/billingAccounts/<your-billing-account-id>/billingRoleDefinitions/24f8edb6-1668-4659-b5e2-40bb5f3a7d7e"
     }
   }
   ```

   - **`principalId`** — the **Object ID** of the CloudMonitor app *in your
     tenant*. Find it under **Microsoft Entra ID → Enterprise applications**,
     search for **`cloudmonitor-beta`**, and copy its **Object ID**.
   - **`principalTenantId`** — your **Directory (tenant) ID**.
   - **`<your-billing-account-id>`** — the same value you used for
     `billingAccountName`.
   - `24f8edb6-1668-4659-b5e2-40bb5f3a7d7e` is the fixed role-definition ID for
     the read-only **EnrollmentReader** role — leave it as-is.
4. Click **Run**. A **200** status means success.
   - **400** — recheck every field.
   - **403** — your account doesn't have permission; sign in as an Account
     Owner or Department Administrator.

### 3c — No billing-account access (or running through a CSP)

Use this if you don't have access to your billing account (for example, your
CSP or managed service provider holds it), or if the MCA limitation above
applies. CloudMonitor reads cost data at the **subscription** scope instead.

1. In the Azure portal, open a **subscription** that CloudMonitor already has
   **Reader** access to (from Step 2).
2. Select **Access control (IAM)** → **+ Add → Add role assignment**.
3. On the **Role** tab, select **Cost Management Contributor**.
4. On the **Members** tab, click **Select members**, search for the
   CloudMonitor application, and select it.
5. Click **Review + assign**.
6. Repeat for each subscription you want cost data from.

:::caution[What you give up with subscription-scope billing]
Because some data only exists at the billing-account level, this method
**cannot** show:

- Marketplace and other billing-account purchases,
- Reservation (RI) **net savings** and utilization (reservation *orders* and
  *details* still appear),
- Microsoft 365 license costs,
- a single holistic view across the whole organization.

Reservation savings specifically require a **Reservation Reader** role at the
*tenant* level and can't be derived from subscription access alone. We
recommend billing-account access ([3a](#3a--microsoft-customer-agreement-mca)
or [3b](#3b--enterprise-agreement-ea-legacy)) whenever possible.
:::

## Step 4 — Set up the cost-data export storage

CloudMonitor receives your detailed cost data through a scheduled Azure Cost
Management export. You create **one dedicated storage account** for these
exports, register the export resource provider, and grant the CloudMonitor
service principal access to it. CloudMonitor authenticates to this storage
account using the service principal you authorized in Step 1 — no access keys
are shared.

**Your data stays in your storage account.** Rather than copying it out,
CloudMonitor reads the exported files in place using a **Microsoft Fabric
OneLake shortcut** — a reference that surfaces your storage account directly
inside our Fabric pipeline, so there's no second copy of your data and no
separate transfer to manage. You can read more about
[OneLake shortcuts](https://learn.microsoft.com/en-us/fabric/onelake/onelake-shortcuts).

:::note[The storage account must be Data Lake Storage Gen2]
Because the Fabric shortcut reads the export over the Data Lake (ADLS Gen2)
endpoint, the storage account must be a **general-purpose v2** account with
**hierarchical namespace** (Azure hierarchical folders) **enabled** — see
Step 4a.
:::

### 4a — Create the storage account

1. In the Azure portal, go to **Storage accounts** and click **Create**.
2. Select the **subscription** and **resource group** to hold it. We recommend
   creating a new resource group dedicated to CloudMonitor.
3. **Name** the storage account per your organization's naming conventions.
4. Leave the default **Standard** performance and **Azure Blob Storage or Azure
   Data Lake Storage Gen2** primary service — this creates a **general-purpose
   v2 (StorageV2)** account.
5. **Region** — choose the region closest to your main workloads to avoid
   egress charges.
6. **Redundancy** — **LRS** is sufficient.
7. On the **Advanced** tab, **enable Hierarchical namespace** (Azure Data Lake
   Storage Gen2 — the "hierarchical folders" option). This is **required** so
   CloudMonitor can read the exports through a Fabric OneLake shortcut.
8. Click **Review + create**.

### 4b — Register the export resource provider

The export API needs the **Microsoft.CostManagementExports** resource provider
registered on the storage account's subscription. **It's often already
registered** — so just check first, and only register it if it isn't.

1. Open **Subscriptions** and select the subscription that holds the new
   storage account.
2. Select **Resource providers**.
3. Search for **Microsoft.CostManagementExports** and check the **Status**
   column. If it shows **Registered**, there's nothing to do. If it shows
   **NotRegistered**, select it and click **Register**.

For more on registering providers, see Microsoft's guide to
[Azure resource providers](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types).

### 4c — Grant CloudMonitor access to the storage account

**Why Storage Account Contributor (and not a read-only role)?** The scheduled
Cost Management export has to **write** your cost files into this account, and
Azure requires the **Storage Account Contributor** role to create and run that
export — a lower, read-only role isn't sufficient. This is a limitation of how
Azure Cost Management exports work, not extra access CloudMonitor wants. The
role is scoped to **this one storage account only** (see the note below).

1. Open the storage account you created in Step 4a.
2. Select **Access control (IAM)** → **+ Add → Add role assignment**.
3. On the **Role** tab, select **Storage Account Contributor**.
4. On the **Members** tab, click **Select members**, search for
   **`cloudmonitor-beta`**, select it, and click **Select**.
5. Click **Review + assign**.

:::note
This **Storage Account Contributor** role applies only to this one storage
account, which exists solely to receive your cost exports. It gives CloudMonitor
no access to your other resources or to the data inside your services.
:::

### 4d — Allow cost-export write operations

1. On the same storage account, open **Configuration**.
2. Set **Permitted scope for copy operations** to **"From any storage
   account"**.
3. Click **Save**.

This lets Azure Cost Management write the scheduled export data into the
account.

## Let us know when you're done

You don't need to send us any IDs. Once you've completed the steps above, just
**email us to let us know it's done** — we can take care of the rest from our
side.

## What happens next

1. **We run a health check** on your setup to confirm the permissions and the
   cost export are working as expected.
2. **We extract your data** and build your CloudMonitor reports.
3. **We email you the link** to your reports, at the address you gave us.

Run into a problem at any point? [Click here to raise a ticket](#chatbox) and
our support team will help.

## Quick reference — everything CloudMonitor asks for

| Scope | Role / permission | How it's granted | Access level |
| --- | --- | --- | --- |
| Subscription / management group | **Reader** | IAM role assignment (Step 2) | Read-only |
| Billing account — MCA | **Billing account reader** | IAM role assignment (Step 3a) | Read-only |
| Billing account — EA | **EnrollmentReader** | Billing REST API (Step 3b) | Read-only |
| Subscription (billing fallback) | **Cost Management Contributor** | IAM role assignment (Step 3c) | Cost data only |
| Cost-export storage account (one dedicated account) | **Storage Account Contributor** | IAM role assignment (Step 4c) | Manage + read this one account only |

Questions at any point? Reach out to your CloudMonitor contact — we're happy to
walk through any step with you.
