# p0 scp

### **Overview** <a href="#overview" id="overview"></a>

The p0 scp command is a drop-in replacement for the standard scp, but with one key advantage: it **automatically requests and provisions SSH access** via P0. You simply specify your source and destination (local or remote), and P0 handles:

1. **Authentication** and key issuance
2. **Access requests** against your SSH integration
3. **Privilege elevation** (optional --sudo)
4. **Invocation** of the underlying scp binary

Use p0 scp anytime you'd otherwise run scp—no need to juggle SSH keys, open tickets, or paste connection strings.

***

### **Prerequisites** <a href="#prerequisites" id="prerequisites"></a>

* **Logged-in user**

```plaintext
p0 login <org-slug>
```

* **SSH integration configured** in your P0 tenant (AWS, Azure, or GCP).
* **Network access** to P0's API and to the target host over SSH.

***

### **Syntax** <a href="#syntax" id="syntax"></a>

```plaintext
p0 scp <source> <destination> [P0-options] [-- SCP-ARGS…]
```

* \<source> / \<destination>

  Either a local path (./file.txt) or remote in the format \<hostname>:\<path>. Exactly one must be remote.
* **P0-options** (before --):
  * `--reason <text>`
  * `--account <account-id>`
  * `--provider <aws|azure|gcloud>`\`
  * `--sudo`
  * `--debug`
* **SCP-ARGS** (after --): all standard scp flags (e.g. -P 2222, -C, etc.)

***

### **Positional Arguments** <a href="#positional-arguments" id="positional-arguments"></a>

|             | <p><strong>Argument</strong></p><p><strong>Description</strong></p> |
| ----------- | ------------------------------------------------------------------- |
| source      | Local or remote source path.                                        |
| destination | Local or remote destination path.                                   |

**Note:** Exactly one of source or destination must specify a remote host (via \<hostname>:). If both or neither do, the command will fail.

***

### **P0-Specific Options** <a href="#p0-specific-options" id="p0-specific-options"></a>

|                  |             |         | <p><strong>Flag</strong></p><p><strong>Alias</strong></p><p><strong>Type</strong></p><p><strong>Description</strong></p> |
| ---------------- | ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| -r               | --recursive | boolean | Recursively copy entire directories.                                                                                     |
| --reason \<text> | —           | string  | Justification for audit logs.                                                                                            |
| --account \<id>  | —           | string  | Cloud account where the instance lives (e.g. AWS account ID).                                                            |
| --provider \<p>  | —           | string  | Which SSH integration to use. One of: aws, azure, gcloud.                                                                |
| --sudo           | —           | boolean | Temporarily add you to sudoers on the target host for the session.                                                       |
| --debug          | —           | boolean | Print detailed debug info (HTTP requests, provisioning logs).                                                            |

***

### **Underlying SCP Options** <a href="#underlying-scp-options" id="underlying-scp-options"></a>

After --, pass any flags supported by your system's scp. Common examples:

* -P 2222 to specify a non-default SSH port
* -C to enable compression
* -i /path/to/key (not needed – P0 provides the key)

```plaintext
p0 scp -r ./dir remote-host:/dest/ -- -P 2222 -C
```

***

### **How It Works** <a href="#how-it-works" id="how-it-works"></a>

1. **Parse arguments**, split P0 flags vs. scp flags at --.
2. **Authenticate** via p0 authenticate().
3. **Determine remote host**: exactly one of source or destination must match \<host>:.
4. **Request SSH access**: calls P0 backend, which spins up a short-lived key and (if --sudo) updates sudoers.
5. **Swap hostnames**: replaces \<hostname> with \<linuxUserName>@\<instanceId>.
6. **Executes** the local scp binary with your flags and the fetched private key.

***

### **Examples** <a href="#examples" id="examples"></a>

#### **1. Copy a File from Local to Remote** <a href="#id-1-copy-a-file-from-local-to-remote" id="id-1-copy-a-file-from-local-to-remote"></a>

```plaintext
p0 scp ./report.pdf prod-web-01:/var/www/reports/
```

* Implicitly targets host prod-web-01.
* Downloads a P0-issued key, performs scp report.pdf ubuntu\@i-0abc123:/var/www/reports/.

***

#### **2. Copy a File from Remote to Local** <a href="#id-2-copy-a-file-from-remote-to-local" id="id-2-copy-a-file-from-remote-to-local"></a>

```plaintext
p0 scp prod-db-server:/var/backups/db.sql ./db.sql
```

* Retrieves /var/backups/db.sql from prod-db-server into your current directory.

***

#### **3. Recursive Directory Copy** <a href="#id-3-recursive-directory-copy" id="id-3-recursive-directory-copy"></a>

```plaintext
p0 scp -r ./configs staging-app-01:/etc/myapp/
```

* Recursively transfers the local configs/ directory.

***

#### **4. Specify Cloud Provider & Account** <a href="#id-4-specify-cloud-provider-and-account" id="id-4-specify-cloud-provider-and-account"></a>

```plaintext
p0 scp ./deploy.sh azure-vm:/home/azureuser/ \
    --provider azure --account sub-12345678
```

* Directs P0 to use your Azure integration on subscription sub-12345678.

***

#### **5. Grant sudo During Transfer** <a href="#id-5-grant-sudo-during-transfer" id="id-5-grant-sudo-during-transfer"></a>

```plaintext
p0 scp --sudo ./upgrade.sh prod-web-01:/tmp/ --reason "Patch deploy"
```

* Adds you to sudoers on prod-web-01 before running scp, so remote file ownerships and permissions can be managed.

***

#### **6. Pass Custom SCP Arguments** <a href="#id-6-pass-custom-scp-arguments" id="id-6-pass-custom-scp-arguments"></a>

```plaintext
p0 scp ./archive.tar.gz bastion-host:/tmp/ \
    -- -P 2222 -C
```

* Uses port 2222 and compression (-C) on the underlying scp call.

***

#### **7. Debugging the Provisioning Flow** <a href="#id-7-debugging-the-provisioning-flow" id="id-7-debugging-the-provisioning-flow"></a>

```plaintext
p0 scp --debug ./file.txt remote-host:/tmp/
```

* Prints API calls, SSH key details, and status messages to stderr.

***

### **Error Conditions** <a href="#error-conditions" id="error-conditions"></a>

* **Both sides remote or both local**

  Exactly one host (source or destination) must be remote.

  Fix: prefix only one argument with \<hostname>:.
* **Azure + custom port**

  Azure SSH does not currently support specifying a port…

  Azure integration only works over default port 22.
* **Could not determine host**

  Could not determine host identifier…

  Ensure your \<hostname>: syntax is correct (no spaces, exactly one colon).
