> For the complete documentation index, see [llms.txt](https://docs.p0.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.p0.dev/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration/azure-bastion-host.md).

# Azure bastion host

When you select the **Azure bastion host** connection type, P0 provisions SSH access through a managed Azure Bastion host. This page covers the requirements, permissions, and setup steps for that connection type.

{% hint style="info" %}
This page is one of two connection types for [bastion host configuration](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration.md). For an overview and the shared subscription steps, start on the [Configure bastion host integration](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration.md) page.
{% endhint %}

## Prerequisites

You must have an Azure Bastion host already deployed in your Azure environment. P0 doesn't create the Bastion host for you. It connects to an existing one.

If you haven't yet deployed a Bastion host, see [Microsoft's Bastion deployment guide](https://learn.microsoft.com/en-us/azure/bastion/tutorial-create-host-portal) to create one first.

Your existing Bastion host must meet the following requirements.

| Requirement      | Details                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------ |
| SKU type         | Must be **Standard** or **Premium** (Basic SKU is not supported because it does not support tunneling) |
| Tunneling        | Must be **enabled** in the Bastion host configuration                                                  |
| IP configuration | Must have at least one IP configuration                                                                |
| Subnet           | Must have an IP configuration with the **AzureBastionSubnet** subnet                                   |

{% hint style="info" %}
If any of these requirements are not met, P0 displays a specific error message during setup indicating which requirement failed. Update your Bastion host configuration in the Azure Portal and retry.
{% endhint %}

## How the connection works

P0 supports two modes for the Azure bastion host connection type:

| Mode                          | Description                                                                       | When to use                                                                             |
| ----------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| **Single bastion host**       | Points directly to a Bastion host resource in the subscription                    | The subscription has its own Bastion host deployed                                      |
| **Subscription bastion host** | References another subscription that already has a single Bastion host configured | Multiple subscriptions share a single Bastion host deployed in a different subscription |

**Single bastion host** is the default mode. Select this when your subscription has its own Bastion host. You provide the Bastion host's Azure resource ID, and P0 validates it against the requirements listed earlier in this topic.

**Subscription bastion host** allows you to reuse a Bastion host from another subscription. When you select this mode, P0 shows a dropdown of subscriptions that already have a single Bastion host configured. The selected subscription's Bastion host is used for SSH sessions in the current subscription.

{% hint style="info" %}
A subscription bastion host can only reference a subscription with a **single** Bastion host. Chaining references (a subscription bastion host pointing to another subscription bastion host) is not supported.
{% endhint %}

## Permissions

P0 creates a custom Azure role scoped to the target subscription during setup. This role grants P0 the minimum permissions needed to establish Bastion-to-VM connectivity and manage Bastion sessions.

**Role name:** `P0 Bastion Host Management - {subscriptionId}`

**Required permissions:**

| Permission                                                        | Purpose                                                                       |
| ----------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| `Microsoft.Compute/virtualMachines/read`                          | Read target virtual machine configuration                                     |
| `Microsoft.Compute/virtualMachines/extensions/read`               | Read virtual machine extensions to confirm the AAD login extension is present |
| `Microsoft.Network/bastionHosts/disconnectActiveSessions/action`  | Disconnect active Bastion sessions during access revocation                   |
| `Microsoft.Network/bastionHosts/getactivesessions/action`         | Enumerate active Bastion sessions to terminate them                           |
| `Microsoft.Network/bastionHosts/read`                             | Read Bastion host configuration and status                                    |
| `Microsoft.Network/networkInterfaces/read`                        | Resolve the target VM's network interface configuration                       |
| `Microsoft.Network/virtualNetworks/peer/action`                   | Peer the Bastion and target virtual networks                                  |
| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings/write`  | Create the virtual network peering that connects the Bastion to the target VM |
| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read`   | Read existing virtual network peerings                                        |
| `Microsoft.Network/virtualNetworks/virtualNetworkPeerings/delete` | Remove the virtual network peering during access revocation                   |

This role is assigned to the service principal created during [Azure app registration](/integrations/resource-integrations/microsoft-azure/azure-app-registration.md).

## Setup steps

Complete the [shared subscription steps](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration.md#get-started) first, then select **Azure bastion host** as the connection type and continue with the following steps.

1. Run the Shell or Terraform steps to create the custom role and assign it to the P0 service principal.
2. Enter the **Standard user role id** of the role that grants standard (non-sudo) access on the target VM. P0 assigns this role at the target VM when a user requests access. P0 recommends the built-in **Virtual Machine User Login** role (`fb879df8-f326-4884-b1cf-06f3ad86be52`); you can also point it at an existing custom role or a new custom role. Run the lookup command shown in the P0 UI to obtain the role definition ID. To build a custom role, see [Create a custom role](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration/create-a-custom-role.md).
3. Enter the **Admin user role id** of the role that grants sudo access on the target VM. This field is required, even if you don't currently allow sudo. P0 assigns the role at the target VM only when a request opts into sudo access, but you must configure it at install time. P0 recommends the built-in **Virtual Machine Administrator Login** role (`1c0163c0-47e6-4577-8991-ea5c82e286e4`); you can also point it at an existing custom role or a new custom role. To build a custom role, see [Create a custom role](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration/create-a-custom-role.md).
4. Select the bastion host mode:

   * **Single bastion host** (default): Provide the Azure Bastion host resource ID. In the Azure Portal, go to the Bastions service, select your Bastion resource, and copy its Resource JSON to obtain the ID.
   * **Subscription bastion host**: Select from the dropdown of subscriptions that already have a single Bastion host configured.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>The Bastion host resource ID follows this format:</p><p><code>/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupId}/providers/Microsoft.Network/bastionHosts/{bastionHostName}</code></p></div>

   P0 validates the Bastion host against all requirements listed in the [Prerequisites](#prerequisites) section. If validation fails, you see a specific error message indicating which requirement was not met.

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

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

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

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

The Bastion host configuration is now complete.

## Manage with the P0 Terraform provider

Instead of running the generated Shell steps, you can register the Azure bastion host connection as code with the [P0 Terraform provider](https://registry.terraform.io/providers/p0-security/p0/latest) using the [`p0_azure_bastion_host`](https://registry.terraform.io/providers/p0-security/p0/latest/docs/resources/azure_bastion_host) resource. This is the recommended path for teams that manage their P0 configuration declaratively.

To connect through a managed Azure Bastion host, stage the component with [`p0_azure_bastion_host_staged`](https://registry.terraform.io/providers/p0-security/p0/latest/docs/resources/azure_bastion_host_staged) to obtain the Bastion Host Management role spec, create that role and assign it to P0's service principal, then complete the installation with `p0_azure_bastion_host` by configuring its `azure_bastion` block. Pass the Bastion host resource ID with the [Standard user role id and Admin user role id](#setup-steps) as the standard and admin VM-access role definition IDs. These resources build on the `p0_azure`, `p0_azure_app`, and `p0_azure_iam_write` resources for the same subscription.

{% hint style="info" %}
To connect through a custom jump host instead of a managed Azure Bastion host, configure the `jump_host` block of the same `p0_azure_bastion_host` resource. No staged resource is needed. See [Custom jump host](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration/custom-jump-host.md#manage-with-the-p0-terraform-provider).
{% endhint %}

For the full argument reference and a worked example, see the [`p0_azure_bastion_host` resource documentation](https://registry.terraform.io/providers/p0-security/p0/latest/docs/resources/azure_bastion_host).

## Troubleshooting

| Error                                                                                   | Cause                                                  | Resolution                                                              |
| --------------------------------------------------------------------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------- |
| "Azure bastion host must be of 'Standard' or 'Premium' type"                            | The Bastion host uses the Basic SKU                    | Upgrade the Bastion host to Standard or Premium SKU in the Azure Portal |
| "Azure bastion host must have tunneling enabled"                                        | Tunneling is disabled on the Bastion host              | Enable tunneling in the Bastion host configuration                      |
| "Azure bastion host must have at least one IP configuration"                            | The Bastion host has no IP configuration               | Verify the Bastion host is configured correctly in the Azure Portal     |
| "Azure bastion host must have an IP configuration with the 'AzureBastionSubnet' subnet" | The Bastion host is not attached to the correct subnet | Attach the Bastion host to a subnet named `AzureBastionSubnet`          |
| "Custom role not found in subscription"                                                 | The shell or Terraform commands did not complete       | Re-run the install commands                                             |
| "Custom role is not assigned to the App Client"                                         | The role assignment was not created                    | Re-run the role assignment command                                      |

## Next step

Proceed to [Install SSH access control](/integrations/resource-integrations/microsoft-azure/install-ssh-access.md) to connect P0 to your Azure VMs.
