# SSH

This topic describes how to request SSH permissions for Amazon Web Services (AWS), Microsoft Azure (Azure) and Google Cloud Platform (GCP) instances. P0 SSH provides full SSH functionality, enabling you to securely manage and configure remote servers.

This guide contains the following sections:

1. [Prerequisites](#prerequisites)
2. [Install the P0 CLI Package](#install-the-p0-cli-package)
3. [Install the P0 SSH Integration in your Cloud](#install-the-p0-ssh-integration-in-your-cloud)
4. [Configure Accounts](#configure-accounts)

## Prerequisites

* Existing P0 account at [p0.app](https://p0.app/)
* Standard terminal application that supports SSH (e.g., Terminal, Command Prompt, PowerShell, or Bash)
* [Node.js](https://nodejs.org/en/download/package-manager) version 20 or later

{% hint style="info" %}
Installing Node.js automatically installs [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [npx](https://www.npmjs.com/package/npx) on your computer.
{% endhint %}

* [AWS](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-creating.html), Azure, and/or [GCP ](https://console.cloud.google.com/welcome?pli=1\&project=amplified-album-197721)account with admin access, where your target instances are hosted
* P0 IAM integrations installed for [AWS](https://docs.p0.dev/integrations/resource-integrations/aws), [Azure](https://docs.p0.dev/integrations/resource-integrations/microsoft-azure), and/or [GCP](https://docs.p0.dev/integrations/resource-integrations/google-cloud)
* (For AWS) Existing [Okta](https://login.okta.com/) and/or [AWS Identity Center](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html) account and an [associated P0 directory integration](https://docs.p0.dev/integrations/directory-integrations/okta)

{% hint style="info" %}
These instructions use [Okta](https://support.okta.com/help/s/article/what-is-okta?language=en_US) to manage user access and permissions.
{% endhint %}

## Install the P0 CLI Package

You must install the [P0 CLI package](https://github.com/p0-security/p0cli) on your computer before you request permissions using SSH:

1. Open your computer's terminal.
2. Navigate to the directory where you'll install the P0 CLI using the following command:

{% code fullWidth="false" %}

```bash
cd <path/to/my/directory>
```

{% endcode %}

{% hint style="info" %}
Ensure you replace `<path/to/my/directory>` with your specific directory path.
{% endhint %}

3. Install the P0 CLI package:

* (Recommended) Run the following command to globally install the P0 CLI package:

```
npm i -g @p0security/cli
```

* Alternatively, use [npx](https://docs.npmjs.com/cli/v8/commands/npx) to run the P0 CLI without installing it:

```
npx p0 ssh private-node --provider gcloud
```

## Install the P0 SSH Integration in your Cloud

{% hint style="info" %}
To configure for Microsoft Azure, follow [configuring SSH access control (via Bastion)](https://docs.p0.dev/integrations/microsoft-azure#configure-ssh-access-control-via-bastion)
{% endhint %}

1. Go to [p0.app](https://p0.app/) in your browser. Select **Integrations**, then under the **Resources** section, click **SSH**.

   <figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-a012a487704fea979454e4d816c8fdcb048238dc%2Fimage.png?alt=media" alt="" width="274"><figcaption></figcaption></figure>
2. From the list of **Available components**, click **SSH access control**.

   <figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-724cb619e488a6781099c96185f4dd7da783a080%2Fimage.png?alt=media" alt="" width="315"><figcaption></figcaption></figure>
3. Click **+ Add account**.

   <figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-63f7e8575e90736437aca173238b01366a23623d%2Fimage.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>
4. From the **Account identifier** dropdown, select your AWS account or GCP project, then click **Next**.

{% hint style="info" %}
Ensure your AWS, Azure or GCP account is connected to P0 and the required integrations are installed. Without this setup no accounts will appear in the **Account identifier** dropdown.
{% endhint %}

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-82b3e7cc908281040ed9a5d4d432642ec3c5cd84%2Fimage.png?alt=media" alt="" width="334"><figcaption></figcaption></figure>

5. Review the configuration and click **Next**. For AWS, you add Regions and VPC IDs (optionally, Instance IDs). For GCP, you add GCP project ID, Zone and instance name.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-3d97787b53bc159cdea1a43639c11f79d75b7248%2Fimage.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-225814d95997968a570d572d98894567bb071a3f%2Fimage.png?alt=media" alt="" width="313"><figcaption></figcaption></figure>

6. (Optional) For AWS, enter a **Grouping tag** to group similar instances.

{% hint style="info" %}

* You can use the **Grouping tag** as the `<instance-name>` when you [Configure an AWS Account](#configure-an-aws-account).
* Once the P0 CLI is installed, you can use the command `p0 request ssh group --name <value>` to combine AWS instances that share the same tag value.
  {% endhint %}

7. Click **Finish** to complete the SSH permissions request.

   <figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-ff9de4757daef57e9beb0505ecfe9a3c856662e3%2Fimage.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

## Configure Accounts

AWS and GCP accounts require different configuration processes. Choose the configuration instructions you need:

* [Configure an AWS Account](#configure-an-aws-account)
* [Configure a GCP Project](#configure-a-gcp-project)

### Configure an AWS Account

1. From the [p0.app](https://p0.app/) site, navigate to the **SSH access control** page, and copy the shell commands displayed.

{% hint style="info" %}
Keep this browser tab open. You will come back to this page in later steps.
{% endhint %}

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-a8ce1286a9de9cf36b72a49768ea0ca7c937b7cd%2Fimage%20(47)%20(2).png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

2. Open a new browser tab and log into your [AWS Management Console](https://aws.amazon.com/console/).
3. Once logged in, on the navigation bar, click **CloudShell**.

{% hint style="info" %}
Alternatively, you can use the search bar to type CloudShell and select it from the results.
{% endhint %}

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-01dd58f0caa7e4072f0d6beebce1d47acbca549c%2Fimage%20(49)%20(2).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

4. AWS CloudShell will open in the console's bottom panel.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-86959eedc1a64bcef9cf48bade6d5e0e5232d565%2Fimage.png?alt=media" alt="AWS login and console" width="375"><figcaption></figcaption></figure>

5. Paste the commands from the **SSH access control** page into AWS CloudShell, and run them. This creates an [AWS Systems Manager (SSM) document](https://docs.aws.amazon.com/systems-manager/latest/userguide/documents.html), which enables P0 to provision sudo access, create a user directory, and configure authorized keys for user authentication.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-481939a94a1a49aba85b39cdc12ea9118ae6a2b3%2Fimage.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

6. Return to the browser tab for the [p0.app](https://p0.app/) **SSH access control** page, click **Next**, and wait for P0 to configure the account.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-b6d8932489c41200ef424dbe66373ecbb21e6e05%2Fimage.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

7. Click **Finish** to complete the configuration.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-e1e97884f843a7b0e9aa77f428550bce7d4aca12%2Fimage.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

8. The account now appears on the SSH access control page.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-a1fed0049a481d5c13f35441ba928a437a5dadc3%2Fimage.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

9. In your terminal, run the following command to log into your P0 organization using Okta:

```
p0 login <your-p0-organization-name>
```

{% hint style="info" %}
Replace `<your-p0-organization-name>` with your P0 organization name. You can find your organization name in the `p0.app` URL (e.g. `https://p0.app/o/your-p0-organization-name`).
{% endhint %}

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-88d65119cc77dc4e5ca9ad75e2272d99fee2d0b0%2Fimage.png?alt=media" alt="Terminal command for login" width="375"><figcaption></figcaption></figure>

11. In the Okta window that displays, enter your activation code and click **Next**.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-7da84d4bf3a31b2bdd3573f4945e88c7d6cd3b6e%2Fimage.png?alt=media" alt="" width="278"><figcaption></figcaption></figure>

12. Return to your terminal and use the following command to request SSH access to your AWS instance or P0 grouping tag:

```
p0 ssh <instance-name>
```

{% hint style="info" %}

* Replace `<instance-name>` with the name of the AWS instance or a P0 grouping tag from [Request AWS or GCP SSH Permissions](#request-aws-or-gcp-ssh-permissions). If you have multiple AWS instances with the same name, you may need to use the `--parent <account_id>` flag within the command.
* Direct `ssh` access is not supported. While direct `ssh` may work, use `p0 ssh` to ensure security controls and compliance.
  {% endhint %}

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-37092d70ae043344f3b9a5775186e295b910134d%2Fimage.png?alt=media" alt="Terminal command for requesting access" width="365"><figcaption></figcaption></figure>

14. Wait for P0 to complete access provisioning. Your terminal displays the status of your request, and indicates whether it was approved or denied.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-584ebe80f75aba2acb7ac40be66e2debfec5c60b%2Fimage.png?alt=media" alt="Terminal command for private node" width="375"><figcaption></figcaption></figure>

15. After SSH access is approved, you can run P0 AWS commands. For example, you can make an access request, or use the following command to list available SSH session destinations:

```
p0 ls ssh session destination
```

{% hint style="success" %}
Congratulations! You're now set up with SSH for P0 on AWS
{% endhint %}

### Configure a GCP Project

1. To display the GCP instances (previously set up for SSH access in [Install the P0 SSH Integration in your Cloud](#install-the-p0-ssh-integration-in-your-cloud)), run the following command in your terminal:

```
p0 ls ssh session destination --provider gcloud
```

2. Copy the name of the GCP instance you want to access from the resulting list. In the following example, `private-node` is the GCP instance name.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-aea514fff0969a8b8bc049ad86074b51253abb5e%2Fimage.png?alt=media" alt="Terminal command GCP private node" width="563"><figcaption></figcaption></figure>

3. In your terminal, run the following command to request SSH access to your GCP instance:

<pre><code><strong>p0 ssh &#x3C;instance-name> --provider gcloud 
</strong></code></pre>

{% hint style="info" %}
Replace `<instance-name>` with the name of the GCP instance, identified in the previous step. If you have multiple GCP instances with the same name, you may need to use the `--parent <account_id>` flag within the command.
{% endhint %}

4. Your terminal displays a message with the wait time for access approval. A subsequent message confirms whether the access request is approved or denied.

<figure><img src="https://3783273641-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQNwGQz62W737pY0FzVb%2Fuploads%2Fgit-blob-79da836cf7adbd154ff72bd0d04b2f1c5dc2d8e9%2Fimage.png?alt=media" alt="Terminal command GCP approval" width="563"><figcaption></figcaption></figure>

5. After SSH access is approved, you can run P0 GCP commands. For example, you can make an access request or use the following command to list available SSH session destinations:

```
p0 ls ssh session destination
```

{% hint style="success" %}
Congratulations! You're now set up with SSH for P0 on Google Cloud.
{% endhint %}

## (Optional) Update Your SSH Configuration for `p0 ssh`

To integrate `p0 ssh` with your native SSH setup, you must update your SSH configuration file. Follow these steps:

1. Open your SSH configuration file using a text editor of your choice. The SSH Configuration file is typically located at `~/.ssh/config`.
2. Append the following lines to your SSH configuration file.

```
Match exec "p0 ssh-resolve %h"
 Include ~/.p0/ssh/configs/*.config
```

{% hint style="info" %}
The line `Match exec "p0 ssh-resolve %h -q"` ensures that `p0 ssh` resolves the hostname dynamically, before making a connection. A hostname will resolve if the following conditions are met:

1. The user is logged into the P0 CLI tool using `p0 login your-org-id`.
2. The user has been granted access to the host or the user is eligible for access.

   **Note:** Eligibility is defined as having a workflow that grants always allowed access to a node or pre-approved access through a group request.

The line `Include ~/.p0/ssh/configs/*.config` loads additional configuration files from `~/.p0/ssh/configs/,` which enables `p0 ssh` to manage custom settings.
{% endhint %}

3. To verify that `p0 ssh` is working correctly with your new set up, run `ssh your-hostname`. If everything is configured properly, ssh will connect to the host machine.

Other tools may use SSH under the hood. A notable example is `git`. If you see spurious output from the P0 CLI when running `git pull`, update your SSH config directive to exclude the `github.com` host:

```
Match host !github.com exec "p0 ssh-resolve %h"
 Include ~/.p0/ssh/configs/*.config
```

You can also add multiple exclusions with wildcards. Exclude all `.com` and `.org` host names from P0:

```
Match host !*.com host !*.org exec "p0 ssh-resolve %h"
 Include ~/.p0/ssh/configs/*.config
```

### Multi-organization SSH access

If you belong to multiple P0 organizations, you can configure host-pattern-based routing so that SSH connections in any shell resolve against the correct P0 organization automatically.

This works by setting the `P0_ORG` environment variable in your `Match exec` directive. When `P0_ORG` is set, `p0 ssh-resolve` passes an `--org` flag to the generated `ProxyCommand`, ensuring the SSH proxy authenticates against the right organization.

**1. Log in to each organization**

```bash
P0_ORG=org-one p0 login
P0_ORG=org-two p0 login
```

**2. Add host-pattern rules to `~/.ssh/config`**

Create a `Match` block for each organization, matching on a host pattern that identifies instances in that organization:

```
Match host *org-one* exec "P0_ORG=org-one p0 ssh-resolve %h"
 Include ~/.p0/ssh/configs/*.config

Match host *org-two* exec "P0_ORG=org-two p0 ssh-resolve %h"
 Include ~/.p0/ssh/configs/*.config
```

Replace `*org-one*` and `*org-two*` with patterns that match your instance names (for example, `*prod1*`, `*staging*`).

**3. Connect**

```bash
ssh my-instance-org-one
```

SSH matches the hostname against the patterns, runs `p0 ssh-resolve` with the correct `P0_ORG`, and connects through the appropriate organization.

{% hint style="info" %}
Each `Match exec` directive runs in its own process, so the `P0_ORG` value set in one block does not affect other blocks. This makes it safe to define multiple organization patterns in the same SSH configuration file.
{% endhint %}
