# Azure

> Azure: fields, the check Connect and verify runs, the tools the agent gets and the read gate, from the connector catalog.

_How-to · Updated 2026-10-21 · Describes release 0.1.164_

> Generated from the connector catalog (`scripts/docs_integration_stubs.py`); the long form of every step is [Connect a datasource](/help/manage-connections.md#connect-a-datasource).

## Overview {#overview}

Azure Resource Manager via the native azure_request tool. The app registration needs an ARM role assignment on the selected resource group or subscription: Access control (IAM) > Add role assignment > Reader (Graph admin consent alone still 403s every read). Writes approval-gated.

Connector type key `azure`, kind `api`, listed under Metrics, Cloud providers, Security findings, Cost / FinOps in the catalog.

## Setup {#setup}

### Before you start {#before-you-start}

- The `datasources.manage` permission; the built-in owner and operator roles carry it.
- An identity the platform can use: **Keyless workload identity (recommended)**, which needs platform setup to cover this workspace ([Keyless cloud access](/portal/connect/keyless) (in the product: `/portal/connect/keyless`)), or a client secret (*Client secret*).
- The full walkthrough for this cloud, setup command included, is [Connect Azure](/help/setup-azure.md).

### Installation {#installation}

Prepare the credential on the vendor side first, scoped to reads: the platform's read gate is a floor, not a substitute for a read-only identity. The connect dialog's **Connection guidance** column names the vendor-side steps and the exact read permissions for this type.

### Configuration {#configuration}

1. Open **Settings · Data in → Data sources** and select **Connect datasource**.
2. Under **Type**, choose **Azure**; the list groups the types by category.
3. Under **Authentication method**, keep **Keyless workload identity (recommended)** or choose the option to use a client secret; the fields the form shows follow that choice, and the rest sit under **Advanced connection settings**.
4. Enter a **Connection name**; the connected list shows it, and per-connection agent tools are named after it.
5. Fill the fields in the table below.
6. Optionally, open **Optional · describe this environment** and say in **What should AIOps know about it?** what this system is and what matters; the agent reads it as the connection's description.
7. Under **Use this connection for**, choose **Investigate only** and select **Connect and verify**.

The form shows these fields, in this order; the **API key** column is the key to send through the REST API.

| Field (portal label) | API key | Stored as |
|---|---|---|
| Subscription ID (scope for write access) | `subscription_id` | plain |
| Resource group (optional — limits the read check and approved-plan execution) | `resource_group` | plain; optional |
| Directory (tenant) ID | `tenant_id` | plain |
| App (client) ID | `client_id` | plain |
| Client secret | `client_secret` | secret, write-only; optional |
| Scope JSON (optional: {subscriptions: []}) | `scope` | plain; optional |

The same connection through the API (`POST /api/aiops/{tenant_id}/datasources`, `datasources.manage`; secret fields go in `secret_values`, which are stored write-only and never echoed):

```json
{
  "type_key": "azure",
  "name": "<name>",
  "description": "<what this is and what matters, for the agent>",
  "config": {
    "subscription_id": "<subscription id>",
    "resource_group": "<resource group>",
    "tenant_id": "<tenant id>",
    "client_id": "<client id>",
    "scope": "<scope>"
  },
  "secret_values": {
    "client_secret": "<client secret>"
  },
  "role": "read",
  "enabled": true
}
```

### Validation {#validation}

**Connect and verify** (and **Test** on the row) runs an Entra client-credentials token, then an ARM read of the configured resource group (or the subscription's resource-group list when none is set).

**You should see** a dialog titled `<connection name> is connected` with **Connected — verified from the control plane** (**Connected — verified by your private-network agent** when your agent ran the check). **Test** on the row later writes `ok · Azure AD token acquired — ARM read verified for subscription resource-group list` (`resource group <name>` in place of the list when one is set) into **Last test**. A green result proves the operation named in its detail and nothing more; **Audit perms** on the row reads what the credential can actually do where the vendor exposes that.

### If something fails {#if-something-fails}

The dialog shows **Needs a fix**, what to fix and the check's own detail; the row is saved either way. Select **Edit**, correct the field the detail names and save again, or select **Retry** once a cause outside the form (network, vendor-side permission) is fixed. The verdict strings **Test** can show (`failed · SSRF guard: '<host>' resolves to non-public address …`, `failed · reachable but auth rejected (HTTP 401/403)`, `failed · HTTP <code> <path>`, `failed · <field> not configured`, `failed · <ExceptionName>: …`) and what to do about each are in [Test a connection and read the failure](/help/manage-connections.md#troubleshooting), and every connection status word is in the [status and error reference](/help/status-and-error-reference.md#connection-statuses). A connected datasource the agent never uses is disabled, write-role, allow-listed to other pillars, or of a type platform staff disabled.

## Data collected {#data-collected}

What the agent gets from a `read` connection of this type:

- `azure_request` — the native tool bound to the first Azure connection (a second one gets `<name>_azure_request`). GET plus these read endpoints over POST — ['providers/microsoft.resourcegraph/resources', 'providers/microsoft.insights/metrics*', 'providers/microsoft.costmanagement/query', 'query', 'api/query'] — flow; every other write is refused in an investigation.

Beside the agent tool, the connection runs account-wide jobs: estate inventory, platform checks, security findings sync and change capture, and on AWS also the hourly service map (Application Signals, X-Ray where Application Signals lists nothing) and built-in detection. `false` under a job's key switches it off: [Jobs this connection runs](/help/read-and-write-roles.md#several-connections-into-one-cloud-account).

An investigation refuses a write through any connection tool, whatever the credential allows (`Investigation connections are read-only. This operation was not executed; prepare an incident change using a write connection and obtain approval.`); a fix runs through a write-role connection after approval. The exact rule table is under **The read/write gate in detail** in [Connections and remediation access](/help/read-and-write-roles.md#read-role-vs-write-role).

## Next steps {#next-steps}

- Choose **Harvest now** on the connection's row in [Data sources](/portal/datasources) (in the product: `/portal/datasources`) first: the inventory read books no model spend ([Estate harvest](/help/estate-harvest-and-xray.md#estate-harvest)); **Discover this connection** starts an Estate x-ray scan, an agent run that spends model budget.
- Select **Discover this connection** in the success dialog to find the services and dependencies behind it: [Launch a scan](/help/estate-harvest-and-xray.md#launch-a-scan).
- See what else each agent needs in [Choose your connection](/help/choose-your-connection.md#agent-needs).
- A fix never runs through this read connection; give approved fixes their own credential with [Write connections and approved fixes](/help/setup-write-connections.md).
