# 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**](https://docs.p0.dev/p0-cli/p0-commands-and-usage/p0-ls)

```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
```
