p0cli: ssh-proxy: How to use the ssh-proxy command

Last updated: May 2, 2025

Overview

The p0 ssh-proxy command implements an SSH ProxyCommand that tunnels your SSH client’s traffic through P0’s managed access workflow. It’s the low-level building block behind p0 ssh and p0 scp—but exposing it directly lets you:

  • Integrate P0’s SSH proxy into your own ~/.ssh/config

  • Reuse a pre-approved SSH request across multiple SSH invocations

  • Customize the private key, port, and provider on the fly


Prerequisites

  • P0 CLI installed (v2024+) and logged in:

p0 login <your-org-slug>
  • A provisioned SSH request JSON file, generated by P0 (e.g. via p0 ssh session <dest>).

  • Your P0-managed private key, typically at ~/.p0/ssh/id_rsa.

  • Network reachability to P0’s API and to the target host via your cloud’s proxy layer (SSM, IAP, or Azure tunnel).


Syntax

p0 ssh-proxy <destination>
    --port <port>
    --provider <aws|azure|gcloud>
  -i, --identityFile <private-key-path>
    --requestJson <request-json-path>
  • <destination>

    P0 session destination name (no slashes), e.g. prod-web-01.

  • --port <port>

    SSH port on the remote instance (usually 22).

  • --provider <aws|azure|gcloud>

    Cloud integration to use for the proxy.

  • -i, --identityFile <path>

    Path to your private key file (PEM).

  • --requestJson <path>

    Path to the JSON file containing your P0 SSH request payload.


How It Works

  1. Authenticate with P0 to fetch fresh credentials.

  2. Read your SSH request JSON and private key.

  3. Select the correct plugin for your cloud provider.

  4. Invoke the provider’s ProxyCommand tool:

    • AWS: aws ssm start-session … --target <instance-id>

    • GCP: gcloud compute start-iap-tunnel … --local-host-port=…

    • Azure: built-in SSH over default port 22

  5. Stream all SSH traffic through that secure tunnel.


Typical Usage Patterns

A. Direct Invocation

If you already have your JSON and key paths, you can manually run:

p0 ssh-proxy my-instance \
  --provider aws \
  --port 22 \
  --identityFile ~/.p0/ssh/id_rsa \
  --requestJson ~/.p0/ssh/requests/my-instance.json

Then in another shell:

ssh -o "ProxyCommand p0 ssh-proxy my-instance --provider aws --port 22 \
  --identityFile ~/.p0/ssh/id_rsa --requestJson ~/.p0/ssh/requests/my-instance.json" \
  ec2-user@my-instance

B. SSH Config Integration

Embed in ~/.ssh/config for seamless ssh my-instance:

Host my-instance
  HostName my-instance
  User ec2-user
  ProxyCommand p0 ssh-proxy %h \
    --provider aws \
    --port %p \
    --identityFile ~/.p0/ssh/id_rsa \
    --requestJson ~/.p0/ssh/requests/%h.json
  • %h → my-instance

  • %p → 22 (default port)

  • Replace paths as needed.


C. Multi-Provider Example

GCP IAP Tunnel

# Generate a session request
p0 ssh session my-gcp-vm --provider gcloud --reason "Debug"
# This writes JSON to ~/.p0/ssh/requests/my-gcp-vm.json

# Use ssh-proxy
p0 ssh-proxy my-gcp-vm \
  --provider gcloud \
  --port 22 \
  --identityFile ~/.p0/ssh/id_rsa \
  --requestJson ~/.p0/ssh/requests/my-gcp-vm.json

# In another shell or config:
ssh -o "ProxyCommand p0 ssh-proxy %h --provider gcloud --port %p \
  --identityFile ~/.p0/ssh/id_rsa --requestJson ~/.p0/ssh/requests/%h.json" \
  your-user@my-gcp-vm

Azure VM

# Provision an SSH session (default port only)
p0 ssh session azure-vm --provider azure

# Hook into proxy
ssh -o "ProxyCommand p0 ssh-proxy %h --provider azure --port 22 \
  --identityFile ~/.p0/ssh/id_rsa --requestJson ~/.p0/ssh/requests/%h.json" \
  azureuser@azure-vm

Advanced Situations

  • Custom Key Location

    Store your key elsewhere:

p0 ssh-proxy target --provider aws --port 2222 \
  --identityFile ~/keys/p0_rsa --requestJson ~/tmp/req.json
  • Non-Default Ports (AWS/GCP)

    If your instance runs SSH on another port, supply it via --port.

  • Scripting

    In automation scripts, combine provisioning and proxy:

dest=my-app
p0 ssh session $dest --provider aws --reason "Deploy"
p0 ssh-proxy $dest --provider aws --port 22 \
  --identityFile ~/.p0/ssh/id_rsa \
  --requestJson ~/.p0/ssh/requests/$dest.json \
| ssh -tt localhost

Tips & Best Practices

  • Automate JSON Management

    P0 writes request JSON under ~/.p0/ssh/requests/<destination>.json. Use that path in your configs.

  • Leverage %h and %p in SSH configs to avoid hard-coding hostnames or ports.

  • Rotate Sessions by regenerating the JSON via p0 ssh session <dest> when TTL expires.

  • Check Support: Not all providers allow custom ports (Azure only supports port 22).

  • Cleanup: P0 auto-removes JSON and config files after proxy exits; no manual cleanup needed.

With p0 ssh-proxy, you gain full control over how your SSH traffic is tunneled through P0’s access services—integrate it anywhere SSH ProxyCommand is supported.