Você colocou uma frase-senha na sua chave SSH, e agora o Windows a pede a cada git push e a cada ssh. A solução é o agente SSH — desbloqueie a chave uma vez e toda conexão depois disso assina em silêncio. A peculiaridade no Windows é que não existe um agente. São três que podem estar rodando ao mesmo tempo, guardam chaves em lugares separados, e uma chave carregada em um é invisível para os outros. Quase todo problema de agente do tipo “funcionava ontem” no Windows é, na verdade, um problema de agente errado. Então este guia começa nomeando-os, depois coloca cada um para rodar, e então decifra os erros que você de fato encontra.
Os três agentes, e por que não compartilham chaves
| Agente | Vem com | Onde escuta | Qual ssh o enxerga |
|---|---|---|---|
| OpenSSH Authentication Agent (um serviço do Windows) | O OpenSSH nativo do Windows | named pipe \\.\pipe\openssh-ssh-agent | ssh.exe em C:\Windows\System32\OpenSSH |
O agente MSYS2 (ssh-agent) | Git for Windows / Git Bash | um socket estilo Unix nomeado por SSH_AUTH_SOCK | o ssh incluído no Git Bash |
| Um agente Linux | dentro da sua distribuição WSL | um socket Unix nessa distribuição | o ssh rodando dentro do WSL |
A lição da tabela: ssh-add no Git Bash carrega uma chave no agente MSYS2, e o ssh.exe nativo do Windows nunca a enxerga — endpoint diferente, armazenamento de chaves diferente. Escolha um agente, carregue suas chaves nele e use o ssh correspondente. Misturá-los é a causa raiz de boa parte da confusão abaixo. O guia do ssh-agent e do ssh-add (em inglês) cobre a mecânica multiplataforma; esta página é a metade específica do Windows.
O serviço OpenSSH Authentication Agent embutido
O Windows 10 e o 11 modernos trazem o OpenSSH e, com ele, um serviço do Windows que roda o agente — mas vem desativado por padrão. Habilite-o uma vez, a partir de um PowerShell elevado (Executar como administrador):
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Automatic o inicia a cada boot, então esta é uma configuração única. Verifique o resultado:
Get-Service ssh-agent | Select-Object Status, StartType
Você quer Running e Automatic. A partir daí, em um PowerShell normal (que não seja o Git Bash) ou cmd, o ssh-add fala com este serviço:
ssh-add # load default keys (id_ed25519, id_rsa, …)
ssh-add $env:USERPROFILE\.ssh\id_ed25519 # load a specific key
ssh-add -l # list loaded key fingerprints
ssh-add -l é o seu primeiro diagnóstico para qualquer falha de login — se a chave que você espera não estiver listada, o agente não pode assinar com ela, por mais que tudo o mais pareça certo.
Para parar de redigitar ssh-add, deixe a primeira conexão carregar a chave para você. Coloque isto em %USERPROFILE%\.ssh\config (o mesmo arquivo ssh_config (em inglês) que o OpenSSH lê em todo lugar):
Host *
AddKeysToAgent yes
Agora o primeiro ssh que precisa de uma frase-senha pergunta uma vez e carrega a chave no serviço como efeito colateral. Como o git e o ssh nativos do Windows usam este serviço, o git push também passa a funcionar em silêncio.
Erro 1058: “unable to start the ssh-agent service”
Você roda Start-Service ssh-agent e recebe:
Start-Service : Service 'OpenSSH Authentication Agent (ssh-agent)' cannot be started due to the following error:
Cannot start service ssh-agent on computer '.'.
... error 1058 ...
O erro 1058 significa que o serviço está desativado — o Windows não inicia um serviço cujo tipo de inicialização é Disabled, e o Start-Service não muda isso por você. Corrija primeiro o tipo de inicialização, depois inicie-o (PowerShell elevado):
Set-Service ssh-agent -StartupType Manual
Start-Service ssh-agent
Manual é suficiente para iniciá-lo sob demanda; use Automatic se quiser que ele suba a cada boot. Se você está em uma máquina gerenciada ou de domínio, uma política de grupo pode tê-lo desativado — nesse caso, o seu administrador precisa permitir o serviço antes que isso se firme.
“error connecting to agent: No such file or directory”
Este vem do ssh do Git Bash / MSYS2, não do serviço do Windows. Significa que o ssh foi informado onde encontrar um socket do agente — via SSH_AUTH_SOCK — e não há nada ali. Duas causas comuns:
-
Nenhum agente está rodando neste shell. O Git Bash não inicia um para você. Inicie-o no shell que você está usando:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519O
evalimporta:ssh-agent -sapenas imprime as variáveis; oevalas define para que osshencontre o socket. Rodarssh-agentsozinho e se perguntar por que nada mudou é o erro clássico. -
SSH_AUTH_SOCKestá obsoleto. Uma variável definida por uma sessão anterior, por um perfil de login ou por outra ferramenta aponta para um socket que não existe mais. Verifique comecho $SSH_AUTH_SOCK, depois ou a remova e inicie um agente novo, ou a corrija para apontar para um que esteja ativo.
Se você preferir usar o serviço do Windows de dentro do Git Bash, chame o binário nativo diretamente — /c/Windows/System32/OpenSSH/ssh.exe — em vez do ssh do MSYS2 no seu PATH. Aí o Git Bash alcança as mesmas chaves que você carregou no serviço, e SSH_AUTH_SOCK deixa de importar.
Chaves no WSL
O WSL é um sistema Linux separado, então tem o próprio agente, o próprio ~/.ssh e o próprio SSH_AUTH_SOCK. Chaves carregadas do lado do Windows não ficam visíveis dentro da sua distribuição, e vice-versa. Você tem duas opções honestas:
- Rode um agente dentro do WSL do jeito Linux comum —
eval "$(ssh-agent -s)"essh-add, ouAddKeysToAgent yesno~/.ssh/configda distribuição. Simples, totalmente isolado, e coberto no guia do ssh-add (em inglês). - Faça uma ponte para o agente do Windows para que os dois mundos compartilhem um único armazenamento de chaves. A receita habitual canaliza o named pipe do Windows para um socket Unix ao qual o
SSH_AUTH_SOCKdo WSL aponta, usandonpiperelay.exejunto comsocat. Funciona bem depois de configurado, mas são peças móveis a mais — recorra a isso só se você realmente precisar da mesma chave dos dois lados.
Qualquer que seja a sua escolha, lembre-se de que ssh-add -l dentro do WSL é uma pergunta diferente de ssh-add -l no PowerShell. Faça a pergunta certa quando for depurar.
Quando o agente está bem, mas o login ainda falha
Se o ssh-add -l mostra sua chave e o servidor ainda diz Permission denied (publickey), o agente fez o seu trabalho — o problema desceu para o authorized_keys do servidor, o usuário errado ou a chave errada sendo oferecida. Essa é outra lista de verificação: Permission denied (publickey), resolvido em ordem (em inglês). E, antes de encaminhar o agente para uma máquina remota com ssh -A, leia por que o encaminhamento do agente é conveniente e perigoso (em inglês) — ele expõe o uso ao vivo das suas chaves na outra ponta.
Como o Termalin lida com isso no Windows
Se fazer malabarismo com serviços, sockets e três armazenamentos de chaves é mais do que você quer pensar, esse é o fluxo de trabalho que o Termalin já traz embutido. Ele roda o próprio agente de chaves em um named pipe do Windows, \\.\pipe\termalin-ssh-agent, e serve as chaves que você já desbloqueou no app pelo protocolo padrão do ssh-agent — de modo que uma ferramenta que fala esse protocolo pode assinar por meio dele sem nenhum serviço do sistema para habilitar, sem linha de eval e sem ssh-add manual. As chaves privadas ficam no app em execução e nunca são gravadas em disco. O propósito desse agente é deixar o próprio servidor MCP do Termalin se autenticar nos seus servidores com as suas chaves sem nunca guardar o material da chave em si — o agente assina, o chamador nunca vê o segredo. É a mesma ideia de um único desbloqueio do serviço OpenSSH, com a configuração do Windows tirada das suas costas.
O Termalin é um cliente SSH gratuito e multiplataforma cujo agente integrado desbloqueia suas chaves uma vez e assina em seu nome — baixe o Termalin, ou leia como ele lida com suas chaves com segurança.