---
name: ssh-setup
description: Generate SSH keys and configure passwordless authentication for GitHub, GitLab, and other Git hosting services
license: MIT
compatibility: opencode
metadata:
  platform: macos,linux
  category: devops
---

## What I do

Guide the complete SSH key setup workflow — from key generation to configuring remote Git hosting services (GitHub, GitLab, Bitbucket) for passwordless push/pull.

## When to use me

Use this skill when the user wants to:
- Generate a new SSH key pair for authentication
- Set up passwordless Git push/pull to GitHub, GitLab, or Bitbucket
- Add SSH keys to a new machine
- Troubleshoot SSH authentication issues
- Configure multiple SSH keys for different accounts (work/personal)

## Workflow

### Step 1: Check existing SSH keys

```bash
ls -la ~/.ssh/
```

Look for existing keys: `id_ed25519`, `id_ed25519.pub`, `id_rsa`, `id_rsa.pub`

### Step 2: Generate a new SSH key (if needed)

**Recommended — Ed25519 (modern, secure):**
```bash
ssh-keygen -t ed25519 -C "your-email@example.com"
```

**Fallback — RSA 4096 (if Ed25519 not supported):**
```bash
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
```

When prompted:
- **Location**: Press Enter for default (`~/.ssh/id_ed25519`)
- **Passphrase**: Optional but recommended. Leave empty for no passphrase, or enter one for added security.

### Step 3: Start ssh-agent and add key

```bash
eval "$(ssh-agent -s)"
```

**Add key to agent:**

For macOS, use `--apple-use-keychain` to store passphrase in Keychain:
```bash
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
```

For Linux:
```bash
ssh-add ~/.ssh/id_ed25519
```

### Step 4: Configure ~/.ssh/config for persistence

```bash
cat >> ~/.ssh/config << 'EOF'
Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519
EOF
```

This ensures the key is automatically added on login.

### Step 5: Add SSH key to GitHub

```bash
# Copy public key to clipboard
pbcopy < ~/.ssh/id_ed25519.pub   # macOS
# cat ~/.ssh/id_ed25519.pub      # Linux (display for manual copy)
```

Then guide the user to:
1. Go to https://github.com/settings/keys
2. Click **New SSH Key**
3. Paste the key, give it a name (e.g., "MacBook Pro")
4. Click **Add SSH Key**

Or use GitHub CLI:
```bash
gh ssh-key add ~/.ssh/id_ed25519.pub --title "MacBook Pro" --type authentication
```

### Step 6: Add SSH key to GitLab

```bash
# Copy public key
pbcopy < ~/.ssh/id_ed25519.pub   # macOS
```

Guide the user to:
1. Go to https://gitlab.com/-/profile/keys
2. Click **Add new key**
3. Paste the key, give it a title
4. Click **Add key**

### Step 7: Test the connection

```bash
ssh -T git@github.com     # "Hi <username>! You've successfully authenticated..."
ssh -T git@gitlab.com     # "Welcome to GitLab, @<username>!"
```

### Step 8: Configure Git to use SSH (if not already)

```bash
git config --global url."git@github.com:".insteadOf "https://github.com/"
git config --global url."git@gitlab.com:".insteadOf "https://gitlab.com/"
```

This ensures `git clone https://github.com/...` automatically uses SSH.

## Multiple SSH keys (work & personal accounts)

Generate separate keys:
```bash
ssh-keygen -t ed25519 -C "work@company.com" -f ~/.ssh/id_ed25519_work
ssh-keygen -t ed25519 -C "personal@email.com" -f ~/.ssh/id_ed25519_personal
```

Configure `~/.ssh/config`:
```
Host github.com-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes

Host github.com-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal
  IdentitiesOnly yes
```

Then clone using the alias:
```bash
git clone git@github.com-work:company/repo.git
git clone git@github.com-personal:personal/repo.git
```

## Troubleshooting

| Issue | Solution |
|-------|----------|
| `Permission denied (publickey)` | Key not added to ssh-agent: `ssh-add ~/.ssh/id_ed25519` |
| `Bad permissions` on ~/.ssh/config | `chmod 600 ~/.ssh/config` |
| SSH key passphrase asked every time | Add `UseKeychain yes` to ~/.ssh/config (macOS) |
| `Could not open a connection to your authentication agent` | Run `eval "$(ssh-agent -s)"` |
| Wrong key being used | Use `ssh -vT git@github.com` to debug which key is tried |
| Key already exists warning | Ask user if they want to overwrite or use the existing key |

## Key notes for the agent

- **NEVER overwrite existing SSH keys** without explicit user confirmation. Always `ls ~/.ssh/` first.
- **Backup before modifying**: `cp ~/.ssh/config ~/.ssh/config.bak.$(date +%s)` before editing.
- **Passphrases are optional** — let the user decide. Explain the tradeoff: security vs convenience.
- **macOS**: Use `--apple-use-keychain` with `ssh-add` to store passphrases in Keychain.
- **Linux**: `ssh-add` without keychain flag, may need `keychain` package for persistence across reboots.
- **Windows/WSL**: WSL users follow Linux instructions; the agent should detect this.
- Recommend **Ed25519** over RSA — it's modern, faster, and more secure.
