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

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

    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

    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

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

    1.1.3 Request sudo

    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

    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

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

    1.2.2 Request sudo

    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.

    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

Windows Note:

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

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

Quick command vault

# 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

Last updated