> ## Documentation Index
> Fetch the complete documentation index at: https://docs.serval.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Azure Resource Manager

> Connect Microsoft Azure's management control plane to Serval so workflows can manage subscriptions, resources, and Azure RBAC role assignments on demand.

## About Azure Resource Manager

Azure Resource Manager (ARM) is the deployment and management control plane for Microsoft Azure - subscriptions, resource groups, role assignments, virtual machines, and every other resource provider are managed through it. The Serval integration lets workflows reach any part of the ARM API through Serval's authenticated proxy, and it ships two ready-to-install workflows for assigning and unassigning Azure RBAC roles. Two built-in health checks confirm that authentication works and that the connection can see your subscriptions.

**Authentication:** Sign in with Microsoft (recommended where available) or Client Credentials with your own Microsoft Entra app registration.

**Data sync:** On-demand only. Nothing is synced into Serval on a schedule - workflows call Azure at run time, and Serval mints or refreshes tokens automatically for each request.

## What the Azure Resource Manager integration enables

| Capability                                      | Description                                                                                                                                                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ARM API requests from workflows                 | Workflows can make any read or write call to Azure Resource Manager, covering subscriptions, resource groups, role assignments, virtual machines, and any other resource provider.                                                                                                                                                                                                         |
| Assign Azure RBAC Role (installable workflow)   | Assigns an Azure RBAC role to a user, group, service principal, or foreign group at a chosen scope. Built-in roles Owner, Contributor, Reader, and User Access Administrator are resolvable by name; custom roles are accepted as role definition IDs. If the principal already holds the role, the workflow reports success with no action taken. Requires installer approval by default. |
| Unassign Azure RBAC Role (installable workflow) | Finds the role assignment matching the principal and role at the given scope and removes it. Errors if the principal does not hold that role at that scope. Requires installer approval by default.                                                                                                                                                                                        |
| Health checks                                   | Two built-in checks, "Test Azure Resource Manager Connection" and "List Azure Subscriptions", verify that the integration can authenticate and can see your subscriptions.                                                                                                                                                                                                                 |

Anything defined in the [Azure Resource Manager API](https://learn.microsoft.com/en-us/rest/api/resources/) can be accessed through Serval.

## Get your credentials

There are two ways to connect. Sign in with Microsoft needs no setup on your side beyond an Azure account with subscription access. Client Credentials requires a Microsoft Entra app registration that you create and authorize yourself.

<Tabs>
  <Tab title="Sign in with Microsoft">
    No credentials to create. You sign in with your own Microsoft account and Serval uses its operator-managed Microsoft Entra app (the same app as the Microsoft Graph integration) to act on your behalf.

    <Note>
      The account you sign in with must have access to at least one Azure subscription (Reader or higher). If it can see zero subscriptions, the connection fails.
    </Note>
  </Tab>

  <Tab title="Client Credentials (your own Entra app)">
    You will create an app registration with a client secret, grant it the Azure Service Management API permission, and give its service principal Azure RBAC roles on every subscription Serval should manage. Microsoft's official guide is [Register an application with Microsoft Entra](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app).

    <Steps>
      <Step title="Open App registrations">
        Sign in to the [Azure Portal](https://portal.azure.com) with admin privileges, open the [Microsoft Entra admin center](https://entra.microsoft.com), and go to **App registrations**.
      </Step>

      <Step title="Register the app">
        Click **New registration**. Name it (for example, "Serval Azure Resource Manager Integration"), set **Supported account types** to **Accounts in this organizational directory only**, leave **Redirect URI** blank, and click **Register**.
      </Step>

      <Step title="Copy the IDs">
        From the app's **Overview** page, copy the **Application (client) ID** (your Client ID) and the **Directory (tenant) ID** (your Tenant ID).
      </Step>

      <Step title="Create a client secret">
        Go to **Certificates & secrets**, then **Client secrets**, then **New client secret**. Add a description, choose an expiration, click **Add**, and copy the secret **Value** immediately. This is your Client Secret.

        <Warning>
          Copy the **Value** column, not the Secret ID - Azure shows the Value only once. If you miss it, create a new secret.
        </Warning>
      </Step>

      <Step title="Grant the API permission">
        Go to **API permissions**, then **Add a permission**, choose **Azure Service Management** (not Microsoft Graph), select **user\_impersonation**, and click **Add permissions**. Then click **Grant admin consent** for your organization and verify the status shows **Granted**.
      </Step>

      <Step title="Assign Azure RBAC roles on each subscription">
        In each subscription Serval should manage, open **Access control (IAM)**, then **Add**, then **Add role assignment**. Pick a role (Reader for read-only, Contributor to manage resources, Owner sparingly), select **User, group, or service principal**, search for your app registration by name, select it, and click **Review + assign**. Repeat for every subscription.

        <Warning>
          The API permission alone grants nothing in Azure. Without RBAC role assignments on each subscription, the connection authenticates but cannot see or manage anything.
        </Warning>
      </Step>
    </Steps>

    <Tip>
      For general Entra app registration concepts such as admin consent and secret rotation, see the [Microsoft 365 (Microsoft Graph)](/sections/integrations/microsoft-graph) integration page.
    </Tip>
  </Tab>
</Tabs>

## Connect in Serval

<Tabs>
  <Tab title="Sign in with Microsoft">
    <Steps>
      <Step title="Click Connect">
        Open the Azure Resource Manager integration in Serval and click **Connect**.
      </Step>

      <Step title="Choose Sign in with Microsoft">
        This option appears (labeled **Recommended**) only when your Serval instance has Microsoft OAuth configured. If you do not see it, use Client Credentials instead.
      </Step>

      <Step title="Complete the Microsoft consent screen">
        Sign in and approve the requested access. Microsoft always shows the consent screen, including when you reauthorize.
      </Step>

      <Step title="Serval detects your tenant">
        Serval lists the subscriptions your account can see, takes the tenant from the first one, and names the connection "Azure (\[first subscription name])". If your account can see zero subscriptions, the connection fails with "no subscriptions found - user may not have access to any Azure subscriptions".
      </Step>
    </Steps>
  </Tab>

  <Tab title="Client Credentials">
    <Steps>
      <Step title="Click Connect, then Client Credentials">
        Open the Azure Resource Manager integration in Serval, click **Connect**, and choose **Client Credentials**.
      </Step>

      <Step title="Fill in all four fields">
        Every field is required (labels show an asterisk), and the submit button stays disabled until all four are filled. Values are trimmed of surrounding whitespace.

        * **Instance Name** - "A friendly name to identify this integration", for example "Production Azure".
        * **Tenant ID** - "Azure AD Directory (Tenant) ID from the Azure Portal".
        * **Client ID** - "Application (Client) ID from your Azure AD App Registration".
        * **Client Secret** - "Client Secret value from your Azure AD App Registration". Entered as a masked password field; paste the secret **Value**, not the Secret ID.
      </Step>

      <Step title="Submit and verify">
        There is no format checking at submit time - a wrong value surfaces at the first token fetch or health check. Common messages include "Please verify your Client ID and Tenant ID in the Azure Portal." and "Client authentication failed for application '\[client ID]'. Please verify the Client ID and Client Secret are correct."
      </Step>
    </Steps>

    <Note>
      **Rotating or updating credentials:** clicking **Reconnect** on a connected integration reopens this same dialog with empty fields - nothing is prefilled. All four fields are required again, so have the full set of values on hand (including the Client Secret) even if you are only changing one of them.
    </Note>
  </Tab>
</Tabs>

## Verifying the connection

The integration includes two health checks.

**Test Azure Resource Manager Connection** verifies that the integration can authenticate by listing your Azure subscriptions.

* Success: "Successfully connected to Azure Resource Manager. Found \[number] subscription(s)."
* Authentication failure: "Authentication failed. Please verify your Azure credentials are correct and have not expired."
* Authorization failure: "Authorization failed. The Azure application may lack permissions to list subscriptions."
* Any other error: "Unable to connect to Azure Resource Manager. Please verify your integration configuration."

**List Azure Subscriptions** lists every subscription visible to the integration and reports how many are enabled.

* Success: "Found \[number] subscription(s), \[number] enabled."
* No subscriptions visible: "No subscriptions found. The integration may lack permissions or there are no subscriptions in this tenant."
* Request errors: "Failed to list Azure subscriptions. Please check your permissions."

<Tip>
  If authentication succeeds but **List Azure Subscriptions** reports "No subscriptions found. The integration may lack permissions or there are no subscriptions in this tenant.", your credentials are valid but the app's service principal has no Azure RBAC roles. Add Reader or higher on each subscription via **Access control (IAM)** and re-run the check.
</Tip>

## Gotchas and troubleshooting

<AccordionGroup>
  <Accordion title="Azure RBAC roles are required on top of API permissions">
    Registering the Entra app and granting the Azure Service Management API permission is not enough: what the connection can actually do in Azure is governed by RBAC role assignments on each subscription. Without them, both health checks fail - "No subscriptions found. The integration may lack permissions or there are no subscriptions in this tenant." is the telltale result. Assign Reader, Contributor, or Owner to the app's service principal per subscription via **Access control (IAM)**, and repeat for every subscription Serval should reach.
  </Accordion>

  <Accordion title="Client secrets expire and the Value is shown only once">
    Entra client secrets have a fixed expiration. Once expired, requests fail with "The client secret for application '\[client ID]' has expired." and the connection health check reports authentication failure. When creating a secret, copy the **Value** column (not the Secret ID) immediately - Azure never shows it again. When it expires, generate a new secret under **Certificates & secrets**, then click **Reconnect** in Serval and enter the new secret Value along with the other connection fields.
  </Accordion>

  <Accordion title="Sign in with Microsoft requires access to at least one subscription">
    The OAuth connect path detects your tenant by listing subscriptions: the tenant comes from the first subscription returned, and the connection is auto-named "Azure (\[first subscription name])". If the signed-in user can see zero subscriptions, the install fails with "no subscriptions found - user may not have access to any Azure subscriptions". Sign in with an account that has at least Reader on a subscription.
  </Accordion>

  <Accordion title="Sign in with Microsoft only appears when platform OAuth is configured">
    The connect dialog shows the **Sign in with Microsoft** button (labeled **Recommended**) only if your Serval instance has Microsoft OAuth credentials configured. Otherwise, Client Credentials is the recommended path. Reauthorizing always brings up the Microsoft consent screen again.
  </Accordion>

  <Accordion title="Reconnecting means re-entering all four fields">
    There is no partial-edit form for this integration. Clicking **Reconnect** on a connected integration reopens the connect dialog with every field empty, and the submit button stays disabled until Instance Name, Tenant ID, Client ID, and Client Secret are all filled in. Keep the full set of values handy when rotating a client secret - you will re-enter the other three values along with the new secret Value.
  </Accordion>

  <Accordion title="Only management.azure.com is reachable">
    The integration's outbound allow-list covers only management.azure.com. Other Microsoft endpoints - Microsoft Graph, Key Vault or Storage data planes, and so on - are not reachable through this integration. Use the [Microsoft 365 (Microsoft Graph)](/sections/integrations/microsoft-graph) integration for Graph calls.
  </Accordion>

  <Accordion title="Role assignment workflow scopes must include a subscription">
    Both bundled RBAC workflows require the scope to contain a subscription segment (used to resolve role definition IDs). Management-group-only scopes are rejected with "Invalid scope: \[scope]. Must include /subscriptions/\[subscription ID]". Note that Assign Azure RBAC Role is idempotent: if the principal already holds the role, it reports success with no action taken.
  </Accordion>
</AccordionGroup>

For deeper reference, see the [Azure Resource Manager documentation](https://learn.microsoft.com/en-us/azure/azure-resource-manager/) and the [Azure RBAC documentation](https://learn.microsoft.com/en-us/azure/role-based-access-control/).

***

Need help? Contact **[support@serval.com](mailto:support@serval.com)** for assistance with your Azure Resource Manager integration.
