# Discover Azure Access Patterns with Teleport Identity Security

Identity Security streamlines and centralizes access management across your entire infrastructure. You can view access relationships in seconds, viewing unified, up-to-date relationships and policies between all users, groups, and computing resources.

Identity Security with Access Graph offers insights into access patterns within your Azure subscription. By scanning users, groups, service principals, and role definitions, it provides a visual representation and aids in enhancing the permission model within your Azure environment. This functionality enables you to address queries such as:

- What resources are accessible to Azure users and roles?
- Which groups belong to other groups and how does that impact resource access?
- How broad or narrow is scoping across the subscription when assigning roles to users and groups?

Utilizing the Access Graph to analyze permissions within an Azure subscription necessitates the setup of the Access Graph service, a Discovery Service, and integration with your Azure subscription.

Access Graph is a feature of the [Teleport Identity Security](https://goteleport.com/platform/identity-security/) product available to Teleport Enterprise edition customers.

To verify that Access Graph is set up correctly for your cluster, sign in to the Teleport Web UI, click the Identity Security sidebar button, and then the Browse menu item. Identities, resources, etc. should be listed.

## How it works

Access Graph discovers Azure access patterns, synchronizes various Azure resources, including users, groups, service principals, and role definitions. These resources are then visualized using the graph representation detailed in the [Identity Security usage page](https://goteleport.com/docs/identity-security/usage.md).

The importing process involves two primary steps:

### Polling Cloud APIs

The Teleport Discovery Service continuously scans the configured Azure subscriptions. At configurable intervals as low as 15 minutes, it retrieves the following resources from your Azure account:

- Users
- Groups
- Service Principals
- Role Definitions
- Role Assignments
- Virtual Machines

Once all the necessary resources are fetched, the Teleport Discovery Service pushes them to Access Graph, ensuring that it remains updated with the latest information from your Azure environment.

### Importing resources

Identity Security’s Access Graph feature visualizes the resources retrieved from your Azure subscription.

## Prerequisites

- A running Teleport Enterprise cluster v17.2.1 or later.

- Identity Security enabled for your account.

- For self-hosted clusters:

  - Ensure that an up-to-date `license.pem` is used in the Auth Service configuration.
  - A running Access Graph node v1.27.0 or later. Check the [Identity Security page](https://goteleport.com/docs/identity-security.md) for details on how to set up Access Graph.
  - The node running the Access Graph service must be reachable from the Teleport Auth Service.

---

WARNING

If you have a cloud-hosted Teleport Enterprise cluster, you can disregard this step, as cloud-hosted Teleport Enterprise already operates a properly configured Discovery Service within your cluster.

---

## Step 1/4. Install the Discovery Service

---

TIP

If you plan on running the Discovery Service on a host that is already running another Teleport service (Auth or Proxy, for example), you can skip this step.

---

Install Teleport on an Azure virtual machine that will run the Discovery Service. This allows for a managed identity attached to the VM to be assigned the correct permissions to fetch the required Azure sources. Alternatively, Teleport can be installed in other environments as long it is attached to a Auth service configured with an Azure OIDC integration. Two options are given below for either 1) using an Azure virtual machine or 2) using Azure OIDC credentials via Entra ID integration.

To install a Teleport Agent on your Linux server:

The recommended installation method is the cluster install script. It will select the correct version, edition, and installation mode for your cluster.

1. Assign teleport.example.com:443 to your Teleport cluster hostname and port, but not the scheme (https\://).

2. Run your cluster's install script:

   ```
   $ curl "https://teleport.example.com:443/scripts/install.sh" | sudo bash
   ```

## Step 2/4. Configure the Discovery Service

To activate the Teleport Discovery Service, add a top level discovery\_service section to the `teleport.yaml` config file. This service monitors dynamic `discovery_config` resources that are set up with the `discovery_group` matching.

discovery-group.

```
discovery_service:
  enabled: true
  discovery_group: discovery-group

```

Notice that if you already operate a Discovery Service within your cluster, it's possible to reuse it as long as the following requirements are met:

- On step 2, you match the `discovery_group` with the existing Discovery Service's `discovery_group`.
- Access Graph service is reachable from the machine where Discovery Service runs.

Once the Auth Service is configured, add the following to the Discovery Service configuration file to enable it for fetching Azure resources:

```
discovery_service:
  access_graph:
    azure:
      - subscription_id: azure-subscription-id

```

The Discovery Service will now periodically fetch resources from your Azure subscription.

## Step 3/4. Activate the Discovery Service

To activate the Discovery Service for fetching Azure resources, you'll need to authorize the identity running the Discovery service. Two options for authorization are available.

**Option 1 - Authorize VM With Managed Identity**

Authorizing an Azure VM for running the Discovery service is the simplest option. The Azure VM can be assigned a Managed Identity, and thus the Discovery service running on it can utilize the permissions associated with that identity. The steps below show how to configure a Managed Identity for an Azure VM. In later steps, the Managed Identity's ID is then assigned a role to the identity using the `./teleport integration configure access-graph azure` command.

**Manually create identity**

### Create a custom role

Enter the name of your Azure resource group in the Azure Portal search box and visit the page for that resource group. On the left navigation sidebar, click the **Access control (IAM)** tab. In the row of buttons at the top of the **Access control (IAM)** panel, click **Add > Add custom role**.

In the **Custom role name** field, enter `teleport-read-vm`.

![Create custom
role](/docs/assets/images/create-custom-role-ca30e0ec44c6b6bb296881c05074b31e.png)

Click the **Permissions** tab, then within the **Permissions** view, click **+Add permissions**.

Enter `Microsoft.Compute/virtualMachines/read` in the search box. Click the **Microsoft Compute** box, then enable **Read: Get Virtual Machine**. Click **Add**.

![Add virtual machine read
permission](/docs/assets/images/read-permission-364f670cde265a090af7b4bed5f2625c.png)

Click **Review + create**, then **Create**.

### Create an Azure managed identity

Visit the [Managed Identities](https://portal.azure.com/#view/hubsextension/browseresource/resourcetype/microsoft.managedidentity%2fuserassignedidentities) view in Azure Portal.

Click **Create**.

Under **Subscription**, **Resource group**, and **Region**, choose the ones that your VM belongs to.

In the **Name** field, enter `teleport-azure`.

![Creating an Azure managed
identity](/docs/assets/images/create-identity-971c43f09067078ca10210b3f6e0f98a.png)

Click **Review + create**, then **Create**.

Once creation finishes, click **Go to resource**. On the page for the new identity, copy the value for the **Client ID** so you can use it later in this guide.

### Assign the `teleport-read-vm` role to the `teleport-azure` identity

Enter the name of your Azure resource group in the Azure Portal search box and visit the page for that resource group. On the left navigation sidebar, click the **Access control (IAM)** tab. In the row of buttons at the top of the **Access control (IAM)** panel, click **Add > Add role assignment**.

Within the **Add role assignment** screen, click **teleport-read-vm**.

![Add a role
assignment](/docs/assets/images/add-role-assignment-c37a06b9783f751c3669b0bddb8f66c1.png)

Scroll to the bottom of the screen and click **Next**.

Within the **Members** tab, in the **Assign access to** field, choose **Managed identity**. Click **Select members**.

On the right sidebar, find the **Managed identity** dropdown menu and select **User-assigned managed identity**. Choose the `teleport-azure` identity you created earlier.

![Select managed
identities](/docs/assets/images/select-managed-identities-7116e647a05b33040cf817c1f8349b55.png)

Click **Select**, then **Review + assign**.

Verify that your **Role** is `teleport-read-vm`, the **Scope** matches your chosen resource group, and the **Members** field includes the `teleport-azure` managed identity you created earlier.

Click **Review + assign** again.

### Attach an identity to your Azure VM

In the [Virtual machines view](https://portal.azure.com/#view/hubsextension/browseresource/resourcetype/microsoft.compute%2fvirtualmachines) of Azure Portal, click on the name of the VM you are using to host the Teleport Service.

On the right side panel, click the **Security/Identity** tab, then within the **Identity** view, click the **User assigned** tab. Click **+Add**, then select the `teleport-azure` identity. Click **Add**.

![Add an identity to a
VM](/docs/assets/images/vm-identity-6f6ea73d08ad47d618bdcfb030a1fee2.png)

Navigate back to **Identity** tab in the page for your Azure VM. You should see the new identity listed in the **User assigned** sub-tab:

![Verifying that you added the
identity](/docs/assets/images/verify-id-358e2a026ffddc22128f929743e8f2f8.png)

---

IMPORTANT

As part of authentication, Teleport will be able to do anything allowed by the identity. If you use a managed identity other than the one created in this guide, we strongly recommend limiting its permissions and scope.

---

**ARM Template**

Create a file named `teleport-create-identity.json` and copy the following into it:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.5.6.12127",
      "templateHash": "2227781763411200690"
    }
  },
  "parameters": {
    "roleName": {
      "type": "string",
      "defaultValue": "teleport-read-vm",
      "metadata": {
        "description": "Friendly name of the role definition"
      }
    },
    "identityName": {
      "type": "string",
      "defaultValue": "teleport-azure",
      "metadata": {
        "description": "Name of the managed identity"
      }
    }
  },
  "variables": {
    "roleDefName": "[guid(resourceGroup().id, string('Microsoft.Compute/virtualMachines/read'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Authorization/roleDefinitions",
      "apiVersion": "2022-04-01",
      "name": "[variables('roleDefName')]",
      "properties": {
        "roleName": "[parameters('roleName')]",
        "description": "A role to allow reading information about Virtual Machines, to be used for Teleport.",
        "type": "customRole",
        "permissions": [
          {
            "actions": [
              "Microsoft.Compute/virtualMachines/read"
            ],
            "notActions": []
          }
        ],
        "assignableScopes": [
          "[resourceGroup().id]"
        ]
      }
    },
    {
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
      "name": "[parameters('identityName')]",
      "apiVersion": "2018-11-30",
      "location": "[resourceGroup().location]"
    }
  ],
  "outputs": {
    "principalID": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identityName'))).principalId]"
    },
    "clientID": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identityName'))).clientId]"
    },
    "roleName": {
      "type": "string",
      "value": "[variables('roleDefName')]"
    }
  }
}

```

Then run the following commands to create the custom role and managed identity:

```
$ DEPLOY_OUTPUT=$(az deployment group create \
--resource-group <your-resource-group> \
--template-file teleport-create-identity.json)
$ PRINCIPAL_ID=$(echo $DEPLOY_OUTPUT | jq -r '.properties.outputs.principalID.value')
$ CLIENT_ID=$(echo $DEPLOY_OUTPUT | jq -r '.properties.outputs.clientID.value')
$ ROLE_NAME=$(echo $DEPLOY_OUTPUT | jq -r '.properties.outputs.roleName.value')
```

Getting a "command not found" error?

This command requires `jq` to be installed on your workstation, which you can do via the [`jq` download page](https://stedolan.github.io/jq/download/).

Next, create another file named `teleport-assign-identity.json` and copy the following into it:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.5.6.12127",
      "templateHash": "2227781763411200690"
    }
  },
  "parameters": {
    "identityName": {
      "type": "string",
      "defaultValue": "teleport-azure"
    },
    "principalId": {
      "type": "string"
    },
    "roleName": {
      "type": "string"
    },
    "vmNames": {
      "type": "array"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "name": "[guid(resourceGroup().id)]",
      "properties": {
        "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', parameters('roleName'))]",
        "principalId": "[parameters('principalId')]"
      }
    },
    {
      "apiVersion": "2018-06-01",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[parameters('vmNames')[copyIndex('vmcopy')]]",
      "location": "[resourceGroup().location]",
      "identity": {
        "type": "userAssigned",
        "userAssignedIdentities": {
          "[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('identityName'))]": {}
        }
      },
      "copy": {
        "name": "vmcopy",
        "count": "[length(parameters('vmNames'))]"
      }
    }
  ]
}

```

Run the following command to assign your custom role to your managed identity and assign the identity to your virtual machines:

```
$ az deployment group create \
--resource-group <your-resource-group> \
--template-file teleport-assign-identity.json \
--parameters principalId="$PRINCIPAL_ID" roleName="$ROLE_NAME" \
vmNames='<list-of-vm-names>'
```

Use the value of `CLIENT_ID` in Step 3.

Use the Managed Identity ID from this option as the principal ID in step 2 of integration command.

**Option 2 - Authorize OIDC Via EntraID Integration**

This option is for running the Discovery service outside of Azure. This requires that Entra OIDC credentials are [configured via the Entra ID integration](https://goteleport.com/docs/identity-security/integrations/entra-id.md). Once the Entra ID integration is configured, the Azure Application is then assigned a role using the `./teleport integration configure access-graph azure` command.

---

TIP

Use the application object ID as the principal ID in step 2 of the integration command.

---

Lastly, add the name of the azure-integration to the configuration, typically this is `entra-id`:

```
discovery_service:
  access_graph:
    azure:
    - subscription_id: azure-subscription-id
      integration: azure-integration

```

## Step 4/4. Set up Access Graph Azure Sync

To configure the Teleport Discovery Service, the Azure managed identity running the Discovery Service within Azure must be given the right permissions to fetch Azure resources. Within the [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), download the [Teleport binary](https://goteleport.com/download/#install-links) in `.tar.gz` format and use it to run the integration command.

You'll need to specify the following in the commands/configuration below:

- teleport-version - The version of Teleport to run the integration command
- azure-subscription-id - The ID of the Azure subscription to fetch resources from
- azure-principal-id - The managed identity (for VM-assigned credentials) or application object ID (for OIDC credentials) that will run the Discovery service
- azure-discovery-role - The name of the new role to create and attach to the above principal (managed identity or application) for permissions to fetch Azure resources

Download and extract the Teleport binary:

```
curl -L https://cdn.teleport.dev/teleport-vteleport-version-linux-amd64-bin.tar.gz | tar xz

```

Run the integration command:

```
./teleport integration configure access-graph azure --principal-id azure-principal-id --role-name azure-discovery-role --subscription-id azure-subscription-id

```
