# Install SSH access

This final step connects P0's SSH integration to your Azure subscription enabling SSH access requests to Virtual Machines.

{% hint style="warning" %}
Complete [Configure bastion host integration](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration.md) before starting this step. SSH access requires the Bastion host configuration from the previous step.
{% endhint %}

## How SSH subscription filtering works

When you configure SSH access, P0 only shows Azure subscriptions that already have a [Bastion host configured](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration.md). If your subscription does not appear in the list, verify that the Bastion host component is installed for that subscription.

## Virtual machine requirements

Any virtual machine you want to connect to via SSH through P0 must meet the following requirements.

| Requirement                     | Details                                                                                                                                                                                                                                                      |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `AADSSHLoginForLinux` extension | Must be **installed** on each Linux VM. VMs without this extension do not appear in the P0 inventory. See [Microsoft documentation](https://learn.microsoft.com/en-us/entra/identity/devices/howto-vm-sign-in-azure-ad-linux) for installation instructions. |
| Network connectivity            | VMs must be in a virtual network that is either: **the same virtual network** as the Bastion host, or **a peered virtual network** connected to the Bastion's virtual network.                                                                               |

## Virtual network peering

P0 automatically manages virtual network (VNet) peering between the Bastion host's network and the target VM's network when they are in different virtual networks.

* **Session start:** If the Bastion host and the target VM are in different VNets, P0 creates bidirectional VNet peering between them. If they share the same VNet, no peering is needed.
* **Session end:** When an SSH session ends, P0 removes the VNet peering — but only if no other active SSH sessions depend on that same peering.

This ensures that VNet peering exists only while SSH sessions are active, and that concurrent sessions sharing the same peering are not disrupted.

## Permissions

### Microsoft Graph API permission

During setup, P0 grants the `User.Read.All` Microsoft Graph API permission to the Azure app registration created in [Step 1](/integrations/resource-integrations/microsoft-azure/azure-app-registration.md). P0 uses this permission to look up the requesting user's identity in your Entra ID directory when initiating an SSH session.

| Permission      | Type        | Purpose                                       |
| --------------- | ----------- | --------------------------------------------- |
| `User.Read.All` | Application | Read user profiles in your Entra ID directory |

This is a read-only permission — P0 cannot modify user profiles.

{% hint style="info" %}
A separate Entra ID directory integration is **not required** for Azure SSH. The `User.Read.All` permission on the app registration is sufficient for P0 to resolve user identities during SSH sessions.
{% endhint %}

### Custom Azure role

During setup, P0 creates a custom Azure role scoped to the target subscription. This role grants P0 the permissions needed to manage VM access and VNet peering during SSH sessions.

**Role name:** `P0 Virtual Machine Management - {subscriptionId}`

**Required permissions:**

| Permission                                                        | Purpose                                |
| ----------------------------------------------------------------- | -------------------------------------- |
| `Microsoft.Compute/virtualMachines/read`                          | Read VM metadata                       |
| `Microsoft.Compute/virtualMachines/extensions/read`               | Check for required VM extensions       |
| `Microsoft.Network/networkInterfaces/read`                        | Read VM network interface details      |
| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read`   | Read existing VNet peering             |
| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings/write`  | Create VNet peering for SSH sessions   |
| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings/delete` | Remove VNet peering after sessions end |
| `Microsoft.Network/virtualNetworks/peer/action`                   | Authorize VNet peering operations      |
| `Microsoft.Network/bastionHosts/getactivesessions/action`         | Query active Bastion sessions          |

If you enable sudo access, the role also includes `Microsoft.Compute/virtualMachines/loginAsAdmin/action` in addition to the standard `Microsoft.Compute/virtualMachines/login/action`.

## Setup steps

1. In P0, open **Integrations → SSH**.

<figure><img src="/files/Jc1ZLvFhR8vU3724eeRG" alt=""><figcaption></figcaption></figure>

2. Click **Add account**.

<figure><img src="/files/lJMukGAmclX8wI3FKKbO" alt=""><figcaption></figcaption></figure>

3. Select the Azure subscription you added during IAM management setup. Only subscriptions with a [Bastion host configured](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration.md) appear in this list.

<figure><img src="/files/CuqgKtWVaqECIAAA9yc4" alt=""><figcaption></figcaption></figure>

4. Run the install commands displayed in the P0 UI. The install steps include:
   * **Microsoft Graph API permissions:** Grant `User.Read.All` to the P0 app registration, reauthenticate to the Microsoft App management API, and approve admin consent.
   * **Subscription targeting:** Set the Azure CLI to the target subscription.
   * **Custom role creation:** Create the `P0 Virtual Machine Management` role with the required permissions.
   * **Role assignment:** Assign the custom role to the P0 service principal.

{% hint style="info" %}
The Microsoft Graph API permission steps require you to reauthenticate with the Azure CLI. Follow the prompts displayed in each step.
{% endhint %}

<figure><img src="/files/tY26JR2xftIKx1KiQ2SP" alt="Azure SSH install commands showing Graph API permissions, subscription targeting, custom role creation, and role assignment steps"><figcaption></figcaption></figure>

<figure><img src="/files/bJwKhHAW5iNZ6kLjwCaj" alt="Azure SSH install commands continued showing role assignment completion"><figcaption></figcaption></figure>

## Optional settings

* **Grouping tag:** specify a tag to enable group SSH access requests
* **Allow sudo:** toggle whether users can request sudo on target nodes

<figure><img src="/files/zICV3uTGIDmq94ogYxYJ" alt=""><figcaption></figcaption></figure>

If you enable sudo, run the additional Shell steps shown to configure sudo access.

When these steps are complete, SSH access is installed. You can now [request SSH access](/integrations/resource-integrations/microsoft-azure/requesting-access.md) to Azure VMs through P0.

{% hint style="info" %}
**Existing customers:** If you previously configured Azure SSH with the Entra ID directory integration installed, you do not need to rerun the SSH install steps. The Entra directory integration already grants the `User.Read.All` permission to the same app registration.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.p0.dev/integrations/resource-integrations/microsoft-azure/install-ssh-access.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
