# p0 ssh

***

### **Overview**

This article shows you how to use the `p0 ssh` command to securely access VMs on both GCP and AWS without long-lived keys or open firewall rules.

* Common concepts: alias discovery, permission requests, ProxyCommand anatomy, cleanup
* How to install and configure prerequisites for each cloud
* Step-by-step examples for interactive shells, one-off commands, port-forwarding, sudo requests
* Provider-specific flags, Windows quoting tips, and troubleshooting
* Security guarantees and quick “vault” of handy commands

***

### **Why use p0 SSH?**

p0 enables secure, auditable, on-demand SSH access to cloud VMs without static keys or open ingress. It handles permission requests, key management, and in-tunnel auditing.

***

### **Prerequisites**

Before you can use `p0 ssh`, ensure you have:

* **Cloud SDK / CLI**
  * GCP: `gcloud SDK` (for `compute start-iap-tunnel`)
  * AWS: `AWS CLI` + **Session Manager plugin** (for `ssm start-session`)
  * Azure: `Azure CLI`
* **Logged-in User**
  * **Authentication**
    * GCP: `gcloud auth login` (OAuth2 refresh token for IAP tunnel)
      * AWS: valid AWS credentials (SSO or API keys)
      * Azure: Valid Azure Credentials or Keys
* **p0 identity**: you must be signed in `p0 login` so requests can be filed on your behalf
* **Project/account mapping**: your org’s p0 config must map SSH destination to real instances

### [**Discover available instance aliases**](/p0-cli/p0-commands-and-usage/p0-ls.md)

```bash
p0 ls ssh session destination --provider <gcloud|aws>
```

Shows the aliases your platform team has registered (GCE instance names or EC2 instance IDs). Listing does *not* imply you already have access—you still need approval.

### **Command anatomy**

```
p0 ssh <destination> --provider <gcloud|aws> [p0-flags] -- [raw SSH flags]
```

* `--provider`: choose your cloud (`gcloud` or `aws`)
* `[p0-flags]`: e.g. `--reason`, `--sudo`, `--debug`
* `--`: separates p0 flags from native SSH options

1. **Hands-on examples**

   **1.1 GCP interactive shell**

   ```bash
   p0 ssh analytics-vm \
     --provider gcloud \
     --reason "Data-ad-hoc – run BigQuery client"
   ```

   **Under the hood:**

   1. Creates a Permission Request (`provider=gcloud`, with your reason).
   2. Notifies approvers (e.g. via Slack).

   **1.1.1 One-off command**

   ```bash
   p0 ssh analytics-vm --provider gcloud -- "df -h /var"
   ```

   Exit code of `df` bubbles up locally—ideal for scripting.

   **1.1.2 Reverse port-forward**

   ```bash
   p0 ssh analytics-vm \
     --provider gcloud \
     -- -NR '*:8080:localhost:9000' \
           -o "GatewayPorts yes" -N
   ```

   **1.1.3 Request sudo**

   ```bash
   p0 ssh db-maint \
     --provider gcloud \
     --sudo \
     --reason "Patch openssl CVE-2025-12345"
   ```

   Adds a NOPASSWD sudoers entry for your user; approvers see `sudo=true` for extra scrutiny.

   **1.2 AWS interactive shell**

   ```bash
   p0 ssh web-prod \
     --provider aws \
     --reason "on-call: investigate 5xx spikes"
   ```

   **Under the hood:**

   1. Approver clicks “Approve” (e.g. in Slack).
   2. p0 grants you a temporary SSM session policy and uploads your public key.
   3. CLI loops `aws ssm start-session` in a ProxyCommand until access is allowed.
   4. Opens the SSH handshake over the SSM tunnel.

   **1.2.1 Local port-forward**

   ```bash
   p0 ssh db-prod --provider aws -- -L 5432:localhost:5432
   ```

   **1.2.2 Request sudo**

   ```bash
   p0 ssh bastion --provider aws --sudo \
       --reason "rotate TLS certs"
   ```

   p0 writes a short-lived `/etc/sudoers.d/p0-<id>` entry granting NOPASSWD ALL to your temp user.

   ```bash
   p0 ssh api-vm --provider aws --debug
   ```

   Prints full `aws ssm start-session` invocation and the final `ssh …` you could re-run manually.

### **Provider-specific flag reference**

* **Common flags**: `--reason`, `--sudo`, `--debug`, `--ttl`, `--request-id`
* **GCP only**: none beyond common (relies on gcloud’s config)
* **AWS only**: you can pass `--region`, `--profile`, etc., which p0 forwards to AWS CLI

{% hint style="info" %}
Windows Note:

In PowerShell, wrap the entire SSH tail in double quotes and escape inner quotes with backslash.

```powershell
p0 ssh analytics-vm --provider gcloud \
  -- "-NR '*:8080:localhost:9000' -o \"GatewayPorts yes\" -N"
```

{% endhint %}

### **Quick command vault**

```bash
# List all aliases (any provider)
p0 ls ssh destination

# Interactive session with explicit GCP project
p0 ssh bastion --provider gcloud --reason "ops"

# Copy local dir to GCP VM (scp over IAP)
p0 scp -r ./dist bastion:/opt/apps --provider gcloud

# Copy build artifact to AWS EC2 (SSM+scp)
p0 scp ./app.tgz web-prod:/opt \
    --provider aws \
    --reason "deploy app 2025-04-29"

# Dry-run debug output
p0 ssh web-prod --provider aws --debug -- -v
```


---

# 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/p0-cli/p0-commands-and-usage/p0-ssh.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.
