# SSH keys for clicked.cloud

Deploys go over SSH with the user's own key. We store the PUBLIC key and push it to their hosting package at our hosting partner. No one else's key reaches their package, and their key reaches nothing else.

## Accepted keys
- `ssh-ed25519` (preferred), or `ssh-rsa` of at least 3072 bits.
- One line, as in a `.pub` file: `ssh-ed25519 AAAAC3Nz… name@laptop`.

## Get or make a key
```sh
cat ~/.ssh/id_ed25519.pub          # already have one? use it
ssh-keygen -t ed25519 -C clicked -f ~/.ssh/id_ed25519   # if not; ask the user first
```
Agents: ask before creating a key, and never touch `~/.ssh/id_ed25519` (the private half).

## Add it to a site
- Dashboard: open the site, then **SSH keys → Add a key**.
- CLI: `clicked keys add` (uses `~/.ssh/id_ed25519.pub`; offers to create one if missing; `--yes` skips the question).
- MCP: `add_ssh_key {siteId, name, publicKey}`.

The key shows as `pending`, then `active`. **Our hosting partner takes about 10 minutes to accept a new key.** Until then SSH answers `Permission denied (publickey)`. Wait and retry; don't add the key again.

## Connect
`site_details` (MCP), the dashboard, or `GET /api/sites/:id` give host, user and port:

```sh
ssh -p 22 <user>@ssh.gb.stackcp.com
```

For `hartleysbakes.co.uk` the user is the package name, e.g. `hartleysbakes.co.uk@ssh.gb.stackcp.com`.

The first connection asks you to trust the server's host key. Agents use `-o StrictHostKeyChecking=accept-new` (trust on first use). We don't publish our hosting partner's host key fingerprints yet.

The user is empty until the site has finished setting up.

## Remove a key
Dashboard, or MCP `remove_ssh_key {siteId, keyId}`. Anything using that key stops being able to deploy.

## Troubleshooting
| You see | Do |
|---|---|
| `Permission denied (publickey)` | Key added under 10 minutes ago: wait. Otherwise check `list_ssh_keys` shows it `active`, and that ssh is offering that key (`ssh -i ~/.ssh/id_ed25519 …`). |
| `Host key verification failed` | First connection with `BatchMode`: add `-o StrictHostKeyChecking=accept-new` (the CLI does). |
| It hangs | Add `-o BatchMode=yes -o ConnectTimeout=15` so ssh fails instead of waiting for a password. |
| `publicKey: rsa keys must be at least 3072 bits` | Make an ed25519 key instead. |
| `that key is already on this site` | It's there; wait for it to go active. |
