Git Permission Denied (publickey) oplossen in 3 minuten
Deze tutorial helpt je de fout Permission denied (publickey) bij Git (meestal via SSH) snel én definitief op te lossen. Je krijgt niet alleen “doe dit commando”, maar ook waarom het werkt, hoe je verifieert wat er misgaat, en hoe je het netjes structureert (meerdere accounts, meerdere keys, CI, Windows/macOS/Linux). Alles is in Markdown en met echte commando’s.
1) Wat betekent Permission denied (publickey) precies?
Wanneer je een Git remote gebruikt met een SSH-URL zoals:
git@github.com:org/repo.git
dan probeert Git via SSH te authenticeren bij de server (GitHub/GitLab/Bitbucket of je eigen server). SSH gebruikt sleutels: een private key op jouw machine en een bijbehorende public key die je bij de server registreert.
De fout:
Permission denied (publickey).
fatal: Could not read from remote repository.
betekent vrijwel altijd één van deze situaties:
- Je SSH key bestaat niet (nog geen key aangemaakt).
- Je SSH agent heeft je key niet geladen (key bestaat wel, maar wordt niet aangeboden).
- Je public key staat niet op GitHub/GitLab (server kent jouw key niet).
- Je gebruikt de verkeerde key (meerdere keys/accounts; SSH kiest de “verkeerde”).
- Je remote URL is verkeerd (SSH i.p.v. HTTPS of verkeerde host/gebruikersnaam).
- Bestandsrechten of key-formaat zijn onjuist (SSH weigert onveilige permissies).
- Enterprise/zelf-hosted: andere hostnaam/poort, of
sshdconfiguratie.
De “3 minuten” zit hem in: snel diagnosticeren welke van bovenstaande het is, en gericht fixen.
2) Sneldiagnose: welke remote gebruik je?
Ga in je repository naar de remote-instellingen:
git remote -v
Voorbeeld output:
origin git@github.com:voorbeeld/repo.git (fetch)
origin git@github.com:voorbeeld/repo.git (push)
Zie je hier git@... of ssh://...? Dan is het SSH. Zie je https://...? Dan is het HTTPS en is publickey niet van toepassing (dan krijg je eerder token/password issues).
Wil je tijdelijk “gewoon door” met HTTPS (bijv. om te testen), dan kan dat:
git remote set-url origin https://github.com/voorbeeld/repo.git
Maar als je SSH wil (aanrader voor dev machines), ga door.
3) Controleer of SSH überhaupt werkt (zonder Git)
Test direct de SSH-auth naar je Git-host. Voor GitHub:
ssh -T git@github.com
Voor GitLab:
ssh -T git@gitlab.com
Voor Bitbucket:
ssh -T git@bitbucket.org
Mogelijke uitkomsten:
A) Je krijgt een succesbericht
Bij GitHub zie je vaak:
Hi gebruikersnaam! You've successfully authenticated, but GitHub does not provide shell access.
Dan is je SSH-auth oké en zit het probleem eerder in remote URL, repo permissies of andere host.
B) Je krijgt “Permission denied (publickey)”
Dan is het echt key/agent/registratie.
C) Je krijgt een host key prompt
Bijv.:
The authenticity of host 'github.com (IP)' can't be established...
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Typ:
yes
Dit is normaal bij eerste connect; het heeft niets met je key te maken.
4) Bestaat je SSH key al?
SSH keys staan meestal in ~/.ssh. Bekijk de map:
ls -la ~/.ssh
Typische bestanden:
id_ed25519(private key)id_ed25519.pub(public key)- of
id_rsa/id_rsa.pub(ouder)
Heb je geen .pub bestanden of geen key-paar? Maak er één aan.
5) Maak een nieuwe SSH key aan (aanrader: Ed25519)
Ed25519 (modern, snel, veilig)
Gebruik je e-mailadres als label:
ssh-keygen -t ed25519 -C "jij@voorbeeld.nl"
Je krijgt vragen:
- Bestandslocatie: druk Enter voor default (
~/.ssh/id_ed25519) - Passphrase: sterk aanbevolen (beschermt je key als je laptop wordt gestolen)
Als je systeem Ed25519 niet ondersteunt (zeldzaam op moderne OS’en), gebruik RSA:
ssh-keygen -t rsa -b 4096 -C "jij@voorbeeld.nl"
Controleer daarna:
ls -la ~/.ssh
Je moet nu een private key en .pub zien.
6) Start de SSH agent en laad je key
Veel “publickey” problemen komen doordat de key niet in de agent zit. De agent “houdt” je sleutel in geheugen zodat SSH hem kan aanbieden.
Linux/macOS (bash/zsh)
Start de agent:
eval "$(ssh-agent -s)"
Voeg je key toe:
ssh-add ~/.ssh/id_ed25519
Controleer welke keys geladen zijn:
ssh-add -l
Je ziet dan iets als:
256 SHA256:... jij@voorbeeld.nl (ED25519)
Windows
Optie 1: Windows OpenSSH (aanrader)
In PowerShell:
Get-Service ssh-agent
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
ssh-add -l
Zorg dat de service automatisch start:
Set-Service -Name ssh-agent -StartupType Automatic
Optie 2: Git Bash
In Git Bash:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l
7) Voeg je public key toe aan GitHub/GitLab/Bitbucket
Kopieer de public key (let op: .pub, nooit je private key).
macOS
pbcopy < ~/.ssh/id_ed25519.pub
Linux (met xclip)
xclip -sel clip < ~/.ssh/id_ed25519.pub
Als je geen clipboard tool hebt:
cat ~/.ssh/id_ed25519.pub
Windows PowerShell
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard
Plak hem daarna in de UI:
- GitHub: Settings → SSH and GPG keys → New SSH key
- GitLab: Preferences → SSH Keys
- Bitbucket: Personal settings → SSH keys
Wacht niet “te lang”; het werkt meestal direct.
Test opnieuw:
ssh -T git@github.com
8) Zet je remote URL correct (SSH)
Als je remote nog op HTTPS staat of verkeerd is, zet hem goed.
GitHub:
git remote set-url origin git@github.com:ORG_OF_USER/REPO.git
GitLab:
git remote set-url origin git@gitlab.com:ORG_OF_USER/REPO.git
Controleer:
git remote -v
Test een fetch:
git fetch
Of push:
git push
9) De nummer-1 “mystery bug”: SSH gebruikt de verkeerde key
Als je meerdere keys hebt (bijv. werk + privé), kan SSH automatisch de verkeerde aanbieden. Dan staat je juiste public key wél op GitHub, maar SSH probeert een andere key → Permission denied (publickey).
9.1 Bekijk wat SSH probeert (verbose debug)
Gebruik -v (of -vvv voor extreem):
ssh -vT git@github.com
Let op regels zoals:
Offering public key: /Users/jij/.ssh/id_ed25519
Offering public key: /Users/jij/.ssh/id_rsa
Als jouw gewenste key niet wordt aangeboden, of de verkeerde eerst, dan moet je SSH configureren.
9.2 Maak/editeer ~/.ssh/config
Open (maak aan als hij niet bestaat):
nano ~/.ssh/config
Voorbeeld: aparte key voor GitHub:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Waarom dit werkt:
IdentityFiledwingt een specifieke key af.IdentitiesOnly yesvoorkomt dat SSH allerlei andere keys uit je agent probeert, wat bij sommige hosts tot rate limits of mis-auth leidt.
Sla op en test opnieuw:
ssh -T git@github.com
9.3 Meerdere accounts op dezelfde host (bijv. 2x GitHub)
Stel je hebt:
- privé GitHub account
- werk GitHub account
Dan maak je twee keys en twee “hosts” in je config:
Host github-privé
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_prive
IdentitiesOnly yes
Host github-werk
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_werk
IdentitiesOnly yes
Dan moet je remote URL ook naar de alias verwijzen:
git remote set-url origin git@github-werk:WERKORG/repo.git
Test:
ssh -T git@github-werk
Dit is dé “pro” oplossing voor meerdere identiteiten.
10) Bestandspermissies: SSH weigert “open” keys (Linux/macOS)
SSH is streng: je private key mag niet leesbaar zijn voor anderen. Als permissies te ruim zijn, krijg je fouten zoals:
Bad permissions on private key
of soms indirect publickey issues.
Fix permissies:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/config
Controleer eigenaar (vooral na kopiëren):
ls -la ~/.ssh
Op Linux kun je ownership herstellen:
sudo chown -R "$USER":"$USER" ~/.ssh
11) Je gebruikt een key met passphrase en het “hangt”/vraagt steeds opnieuw
Als je key een passphrase heeft (goed), wil je niet bij elke push opnieuw intypen. De agent lost dat op, maar je moet zorgen dat hij blijft draaien.
macOS: Keychain integratie
Je kunt je key in Keychain laten opslaan.
Voeg toe:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
En in ~/.ssh/config:
Host github.com
UseKeychain yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
Linux: autostart agent via je desktop omgeving
Dit verschilt per distro. In veel gevallen start je session manager al een agent. Als niet, kun je in je shell init (bijv. ~/.bashrc of ~/.zshrc) iets plaatsen, maar doe dat bewust (niet elke shell opnieuw agents starten). Vaak is de beste route: gebruik je desktop keyring (GNOME Keyring / KDE Wallet).
12) CI/CD of servers: “Permission denied (publickey)” in pipelines
In CI (GitHub Actions, GitLab CI, Jenkins) komt deze fout vaak doordat:
- de private key niet aanwezig is in de runner
- de key geen toegang heeft tot de repo
known_hostsontbreekt (host key verification faalt)- je gebruikt deploy keys vs user keys verkeerd
12.1 Minimale SSH setup in een Linux runner
Voorbeeld (conceptueel) stappen:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# private key uit secret env var schrijven
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
# known_hosts vullen (voorkomt interactive prompt)
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
git fetch
Belangrijk:
- Gebruik bij voorkeur een deploy key per repo (alleen read of read/write).
- Of gebruik een machine user met beperkte rechten.
13) Minder voorkomende oorzaken (maar wel echt)
13.1 Je probeert de verkeerde user
Voor GitHub/GitLab is de SSH user vrijwel altijd git, niet jouw username.
Goed:
ssh -T git@github.com
Fout:
ssh -T jouwnaam@github.com
13.2 Je gebruikt een custom poort of enterprise host
Bij self-hosted GitLab of GitHub Enterprise:
ssh -T git@git.voorbeeldbedrijf.nl
Als SSH op poort 2222 draait:
ssh -p 2222 -T git@git.voorbeeldbedrijf.nl
In ~/.ssh/config:
Host git-bedrijf
HostName git.voorbeeldbedrijf.nl
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519_werk
IdentitiesOnly yes
Remote URL:
git remote set-url origin git@git-bedrijf:team/repo.git
13.3 Je key is in een “nieuw” formaat dat oude SSH niet snapt
Oude systemen kunnen moeite hebben met moderne key formats. Meestal is de fix: update OpenSSH. Op Ubuntu:
sudo apt update
sudo apt install openssh-client
Op macOS: update via systeemupdates (of Xcode CLT).
14) Checklist: in 60 seconden naar de oorzaak
Volg dit exact en je vindt bijna altijd de boosdoener:
- Remote checken
git remote -v - SSH test
ssh -T git@github.com - Key aanwezig?
ls -la ~/.ssh - Agent keys
ssh-add -l - Verbose debug
ssh -vT git@github.com - Config afdwingen
~/.ssh/configmetIdentityFile+IdentitiesOnly yes - Public key geregistreerd?
cat ~/.ssh/id_ed25519.puben in Git host UI plakken.
15) Complete “golden path” (alles in één keer)
Als je gewoon een frisse, correcte setup wilt (macOS/Linux), run:
# 1) Key maken (als je er nog geen hebt)
ssh-keygen -t ed25519 -C "jij@voorbeeld.nl"
# 2) Agent starten en key toevoegen
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# 3) Public key tonen (kopieer deze naar GitHub/GitLab)
cat ~/.ssh/id_ed25519.pub
# 4) SSH testen
ssh -T git@github.com
En als je meerdere keys hebt of je wil het afdwingen:
cat >> ~/.ssh/config <<'EOF'
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
Test opnieuw:
ssh -T git@github.com
16) Veelgemaakte fouten (en hoe je ze herkent)
Fout: je hebt de private key geüpload i.p.v. public key
- Public key eindigt op
.puben begint vaak metssh-ed25519 AAAA... - Private key bevat blokken zoals
-----BEGIN OPENSSH PRIVATE KEY----- - Oplossing: verwijder de gelekte key, maak een nieuwe, upload alleen
.pub.
Fout: je zit in de verkeerde repo of hebt geen rechten
Je SSH-auth kan slagen, maar push faalt met repo-permissions. Check:
ssh -T git@github.com
Als dat werkt maar git push niet, controleer of je account toegang heeft tot de repo en of de remote naar de juiste organisatie wijst.
Fout: je gebruikt een deploy key die alleen read-only is
Dan werkt git fetch wel, maar git push niet. In GitHub kun je deploy keys read/write zetten.
17) Wanneer is HTTPS beter?
SSH is ideaal voor developers. HTTPS is soms makkelijker voor:
- omgevingen waar SSH geblokkeerd is
- snelle test zonder keys
- sommige corporate proxies
Maar moderne Git hosts vereisen bij HTTPS vaak een Personal Access Token. Als je SSH eenmaal goed hebt staan, is het meestal het soepelst.
18) Samenvatting (de kern)
Permission denied (publickey) los je op door te zorgen dat:
- Je een SSH key-paar hebt (
ssh-keygen). - Je private key is geladen in de agent (
ssh-add). - Je public key is geregistreerd bij je Git host.
- SSH de juiste key gebruikt (
~/.ssh/configmetIdentityFileenIdentitiesOnly yes). - Je remote URL klopt (
git@host:org/repo.git).
Als je nu nog vastloopt, plak dan (geanonimiseerd) de output van:
git remote -v
ssh -vT git@github.com
ls -la ~/.ssh
ssh-add -l
Dan is het doorgaans binnen één ronde exact te pinpointen waar het misgaat.