# SOP: SSH Key Management & Access (Zero Trust)
**Purpose:** Standardize the creation, storage, and usage of SSH keys for accessing internal homelab services (Gitea, servers, etc.) protected by Cloudflare Tunnels, without opening firewall ports.
**Prerequisites:**
* **Client:** Windows 10/11 with OpenSSH Client installed.
* **Software:** Keeper Password Manager (Desktop App), `cloudflared` daemon.
* **Network:** Cloudflare Tunnel configured for the target service (SSH protocol).
---
## 1. Key Generation
Use **Ed25519** for all new keys (faster, smaller, more secure than RSA).
1. Open PowerShell.
2. Generate a new key pair (replace `service` with app name, e.g., `gitea`, `prod-server`):
```powershell
ssh-keygen -t ed25519 -C "davisdre@service" -f "$env:USERPROFILE\.ssh\id_ed25519_service"
```
3. **Do not** set a passphrase if relying on Keeper (Keeper protects the key).
## 2. Storage & Agent Setup (Keeper)
We do not store private keys permanently on the local disk. They live in Keeper and are injected into memory via the SSH Agent.
1. **Create Record:** Create a new record in Keeper (e.g., "SSH Key - Gitea").
2. **Attach Keys:** Upload the `.pub` (Public) and the private key file (no extension) to the record attachments or dedicated SSH Key fields.
3. **Enable Agent:**
* In Keeper Desktop: Go to **Settings > SSH Agent**.
* Ensure **Enable SSH Agent Integration** is ON.
* Select the key record you just created and ensure it is listed/active.
4. **Cleanup:** Delete the **private** key file from your local `.ssh` folder. You may keep the `.pub` file for reference.
## 3. Client Configuration (`config`)
Configure the local SSH client to route traffic through Cloudflare and use the Keeper agent.
1. Open your config file: `C:\Users\davis\.ssh\config`.
2. Add a new block for the service.
* **Note:** Do *not* hardcode `IdentityAgent` lines; rely on the `SSH_AUTH_SOCK` environment variable set by Keeper.
```text
# Template for Cloudflare Tunnel Services
Host service.davisdre.com
User git
# Proxy traffic via Cloudflare (requires cloudflared installed)
ProxyCommand cloudflared access ssh --hostname %h
```
## 4. Service Configuration
1. Copy the content of your **Public Key** (`.pub` file).
2. Navigate to the Service (e.g., Gitea Settings > SSH / GPG Keys).
3. Add Key and paste the string (starts with `ssh-ed25519`).
## 5. Connection Verification
Before using the tool (VS Code, git, etc.), verify the handshake in PowerShell.
1. **Unlock Keeper:** Ensure the vault is open.
2. **Test Connection:**
```powershell
ssh -T git@service.davisdre.com
```
3. **Expected Output:**
* *First time:* Prompts to verify host fingerprint (Type `yes`).
* *Success:* `Hi there...! You've successfully authenticated...`
---
## Troubleshooting
| Issue | Check |
| --- | --- |
| **Permission Denied (publickey)** | 1. Is Keeper unlocked?
2. Run `ssh-add -l` to see if keys are loaded.
3. Ensure `git config core.sshCommand` is set to Windows OpenSSH. |
| **TLS Handshake Failure** | Cloudflare SSL mismatch. Ensure the tunnel hostname is not 4th level (e.g., use `git-ssh.domain.com`, NOT `ssh.git.domain.com`). |
| **"Unknown Port" / Proxy Error** | Ensure `cloudflared` is installed and the Tunnel Public Hostname is set to `SSH` service (not HTTP). |
---
### **Git Configuration (One-Time Setup)**
Ensure Git uses the Windows Native SSH (which talks to Keeper) rather than the bundled MinGW SSH.
```powershell
git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"
```