Deploy Error Decoder

'Permission denied (publickey)' — fix SSH and git key auth

Quick answer: Permission denied (publickey) means the SSH server rejected every key you offered. Either your key isn't loaded into the agent, isn't added to the host (GitHub/GitLab/your server), or doesn't match the account. Test with ssh -T [email protected], confirm a key is available with ssh-add -l, and add your public key to the host.

What the error looks like

Git can't authenticate, so it can't read the repo:

[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

The keyword is publickey: the server only accepts key auth and none of your keys were accepted. This is about which key reaches the server, not the repo URL.

Why it happens

No key loaded in the agent

ssh-add -l says "The agent has no identities" — nothing is offered to the server.

The public key isn't on the host

You generated a key but never added the .pub to GitHub/GitLab or the server's authorized_keys.

Right key, wrong account

The key is attached to a different account than the repo grants access to.

Key file permissions too open

SSH refuses to use a private key that's group/world-readable (must be 600).

Diagnose it in three steps

1

See which keys are offered

ssh -vT [email protected] 2>&1 | grep -i 'offer\|publickey'
ssh-add -l        # any identities loaded?
2

Make sure you have a key

ls ~/.ssh/*.pub || ssh-keygen -t ed25519 -C "[email protected]"
ssh-add ~/.ssh/id_ed25519
3

Add the public key to the host

cat ~/.ssh/id_ed25519.pub      # copy this to GitHub/GitLab settings
# or, for your own server:
ssh-copy-id user@server
The real fix

One key, loaded, added, and locked down

A reliable setup: an ed25519 key, loaded into the agent, with the public half on the host and the private half at mode 600. Pin it per-host so the right key is always offered:

chmod 600 ~/.ssh/id_ed25519

# ~/.ssh/config
Host github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
How Infraveil handles this

Key-based trust, no shared passwords

Key auth is exactly the model Infraveil is built on. The agent that runs on your own servers authenticates to the control plane with its own keys — never a shared password — and verifies signatures on what it's told to run. Once your repo access works, deploys flow through a path that's approval-gated and recorded, so access is provable, not assumed.

The agent uses per-host keys and signature verification, not shared secrets
Every deploy and access event is recorded in a tamper-evident trail
Runs on servers you control — you own the keys and the host

Frequently asked questions

What does 'Permission denied (publickey)' mean?

The SSH server accepts only key authentication and rejected all the keys your client offered. Usually no key is loaded, the public key isn't on the host, or it's tied to the wrong account.

How do I see which SSH key is being used?

Run ssh -vT [email protected] and read the verbose output for which identity files are offered, or ssh-add -l to list loaded keys.

How do I add my SSH key to GitHub?

Copy your public key (cat ~/.ssh/id_ed25519.pub) and paste it into GitHub → Settings → SSH and GPG keys. Then test with ssh -T [email protected].

Why does SSH ignore my key?

Often the private key's permissions are too open — SSH requires chmod 600. It can also be that the key isn't loaded into the agent or isn't referenced for that host in ~/.ssh/config.