GitHub SSH on a VPS (Reliable Deploy Access)

Category: On-Premises & Private Cloud

Tags: podman, ssh


The first time I tried git pull on the VPS to ship an update, GitHub slammed the door:

Invalid username or token. Password authentication is not supported

Pasting a personal access token onto the server worked once but felt wrong — tokens expire, end up in shell history, and bind the deploy to a single human account. An SSH Deploy Key fixes all three in one move.

This is the setup I settled on for every pull-based deploy since.

Create a dedicated SSH key on the VPS

A key that lives only on this VPS, labelled so I can identify it in the GitHub UI later:

mkdir -p ~/.ssh && chmod 700 ~/.ssh
ssh-keygen -t ed25519 -C "vps-website" -f ~/.ssh/id_ed25519 -N ""
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
cat ~/.ssh/id_ed25519.pub

Ed25519 over RSA because it’s shorter, faster, and GitHub has supported it for years now. Copy the printed public key for the next step.

Add the key as a Deploy Key

In the repository on GitHub:

  • Settings
  • Deploy keys
  • Add deploy key

I keep it read-only unless the VPS actually needs to push — which for pull-based deploys it never does. A read-only deploy key is strictly less dangerous than a PAT: it’s scoped to a single repository, can’t be used to escalate elsewhere, and doesn’t expire.

Trust GitHub host keys

Pre-seeding known_hosts avoids the interactive “Are you sure?” prompt during the first git clone in a non-interactive deploy script:

ssh-keyscan github.com >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts

Test SSH access

ssh -T git@github.com

A friendly “Hi <repo>! You’ve successfully authenticated…” message means the key is live. If it fails here, fix it before touching the repo remote.

Switch the repository remote from HTTPS to SSH

cd /opt/website
git remote set-url origin git@github.com:adrian-altner/website.git
git remote -v
git fetch
git pull

From this point on, deploys don’t involve any interactive authentication at all.

Optional: explicit SSH config

For multi-key hosts or anywhere I want strict “use only this key for this host” behaviour:

# ~/.ssh/config
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
chmod 600 ~/.ssh/config

IdentitiesOnly yes is the important one — it stops ssh from offering every key the agent knows about before trying the right one, which is what usually causes “too many authentication failures” errors on machines with more than a couple of keys.

Quick troubleshooting

  • Permission denied (publickey) — the key isn’t attached to the right repo, or to the right account. Double-check under the repository’s Deploy keys, not your personal SSH keys.
  • Repository not found — usually a typo in the remote URL, or the deploy key is attached to a different repo than you think.
  • Host key verification failedknown_hosts is missing the GitHub entry. Re-run ssh-keyscan github.com >> ~/.ssh/known_hosts.

What to take away

  • Deploy Keys are scoped, non-expiring, and read-only by default — a better fit for servers than PATs.
  • Ed25519 keys are the sensible default in 2026; RSA buys you nothing here.
  • Pre-seed known_hosts so non-interactive deploys don’t prompt.
  • IdentitiesOnly yes saves hours of debugging on hosts with multiple SSH identities.
  • Deployments should depend on machine identity, not a password a human types.