Como uma checklist de prontidão SSH muda a segurança dos agentes
Use esta checklist de prontidão SSH para testar análise de resultados, identidade de host, idempotência, aprovações e estados remotos desconhecidos antes de dar acesso ao shell a agentes.

HTTP somente leitura é um primeiro canal tolerante a erros para um agente. A solicitação tem um método, um alvo limitado, um código de status, cabeçalhos e, em geral, um corpo com formato documentado. Um GET que falha normalmente não altera o serviço. Ainda é possível lidar mal com credenciais ou expor dados sensíveis, mas o modelo de execução oferece aos revisores algo compacto para avaliar.
SSH muda a unidade de risco. O agente não chama uma operação definida. Ele envia texto para um shell remoto cujo comportamento depende da conta de login, shell, diretório de trabalho, ambiente, sistema operacional, ferramentas instaladas, regras de aspas e estado atual da máquina. Um comando pode ter sucesso parcial, desconectar antes de informar o resultado e deixar a próxima repetição livre para executar o trabalho duas vezes.
Isso não torna SSH inadequado para agentes. Significa que «o canal HTTP funcionou» é uma evidência fraca para adicionar SSH. O teste de admissão precisa cobrir cinco propriedades distintas: análise confiável de resultados, identidade de host verificada, comandos seguros para repetição, aprovações que descrevem consequências e tratamento explícito de estado remoto desconhecido. Se faltar uma delas, mantenha o segundo canal desativado.
Trate SSH como um modelo de execução diferente
A prontidão para SSH começa por reconhecer que um shell remoto não é um transporte HTTP com outra URL. APIs HTTP expõem operações escolhidas pelo servidor. SSH expõe um interpretador escolhido pela conta remota e pede que seu cliente leve até ele uma string de comando não estruturada.
Com uma chamada HTTP somente leitura, o revisor muitas vezes consegue inferir o efeito por GET, pelo host e pelo caminho. Uma resposta como o status 404 também tem um lugar convencional no protocolo, mesmo que a aplicação lhe dê um significado específico do domínio. Com SSH, test -f /srv/app/release && cat /srv/app/release pode retornar 1 porque o arquivo não existe, enquanto cat /srv/app/release pode retornar 1 porque a permissão foi negada. Se o analisador reduzir ambos a «comando falhou», o agente não conseguirá decidir com segurança o que fazer.
O ambiente remoto também muda o significado. sed -i se comporta de forma diferente entre sistemas operacionais comuns. Um shell de login pode carregar arquivos de inicialização que imprimem avisos em stdout. PATH pode encontrar um invólucro em vez do binário esperado. Configurações de localidade podem alterar diagnósticos legíveis por pessoas. Um pseudo-terminal pode misturar comportamentos destinados a uma pessoa com um comando destinado a um analisador. Nenhuma dessas variáveis aparece em um esquema típico de solicitação HTTP.
Escreva um contrato de canal antes de habilitar comandos. Ele deve indicar o usuário remoto, hosts aceitos, shell, diretório inicial, política de ambiente, se pseudo-terminal é proibido, tempo máximo de execução, limites de saída e o envelope exato do resultado. Fixe caminhos de executáveis para ações sensíveis. Defina uma localidade conhecida quando precisar interpretar texto. Prefira saída de máquina do programa remoto, mas nunca presuma que a opção JSON de um programa torna estruturado o shell ao redor dele.
Use uma sondagem não interativa como primeiro portão:
/usr/bin/ssh \
-o BatchMode=yes \
-o StrictHostKeyChecking=yes \
-o ConnectTimeout=10 \
-T [email protected] \
'umask 077; printf "%s\n" "{\"probe\":\"ssh-ready\",\"version\":1}"'
A documentação do OpenSSH descreve BatchMode=yes como uma opção que desativa prompts, incluindo prompts de senha e confirmação de chave de host. -T desativa a alocação de pseudo-terminal. StrictHostKeyChecking=yes recusa chaves desconhecidas ou alteradas. O stdout esperado é um único objeto JSON, stderr está vazio e o status de saída remoto é zero. Teste cada desvio separadamente. Um sistema que não consegue distinguir um host desconhecido de JSON malformado não passou por este portão.
Torne o envelope de resultado inequívoco
A análise de resultados só está pronta quando erros de transporte, término remoto, stdout e stderr permanecem separados. Colapsá-los em um único campo de texto cria uma perigosa falsa confiança.
A RFC 4254 define stdout como dados de canal e stderr como dados estendidos de canal. Ela também define mensagens exit-status e exit-signal, mas a redação importa: enviar um status de saída é recomendado, não obrigatório, e o cliente pode ignorá-lo. O OpenSSH oferece uma convenção local útil sobre esse protocolo. Seu comando ssh sai com o status do comando remoto, ou com 255 quando ocorre um erro.
Não transforme essa convenção em verdade universal. Um programa remoto pode sair com 255, colidindo com o valor de erro do cliente OpenSSH no limite do processo. Um servidor ou biblioteca pode omitir a mensagem exit-status. Um sinal não é o mesmo que uma saída comum diferente de zero. O canal pode fechar depois de produzir saída, mas antes de seu cliente receber um status terminal.
Seu resultado interno deve parecer um registro tipado, não uma transcrição:
{
"phase": "completed",
"transport": "ok",
"host": "host.example",
"host_key_fingerprint": "SHA256:verified-value",
"exit_status": 0,
"exit_signal": null,
"stdout": "{\"state\":\"present\",\"release\":\"2026.07\"}\n",
"stderr": "",
"truncated": false,
"started_at": "request timestamp",
"finished_at": "result timestamp"
}
Mantenha exit_status anulável. Faça phase distinguir ao menos rejeitado, não iniciado, iniciado, concluído e desconhecido. Registre truncamento como dado, nunca corte a saída silenciosamente e entregue o restante ao agente como se estivesse completo. Anexe a impressão digital verificada usada naquela conexão, não apenas o nome de host solicitado pelo agente.
Em seguida, teste uma matriz de resultados. Execute um comando que tenha sucesso sem saída, outro que saia com 7 após escrever nos dois fluxos, outro encerrado por sinal, outro que ultrapasse o prazo, outro que emita UTF-8 inválido se sua pilha permitir bytes e outro que exceda cada limite de saída. Derrube a conexão do cliente enquanto um comando remoto dorme e depois inspecione o resultado. Seu adaptador não deve inventar exit_status: 0, inferir sucesso a partir de stdout nem chamar um timeout de «falha» quando não puder provar se o comando foi executado.
A composição de shell merece testes próprios. POSIX diz que um pipeline normalmente informa o status de seu último comando, a menos que pipefail esteja habilitado. Assim, generate | upload pode informar sucesso porque upload aceitou uma entrada vazia depois que generate falhou. Não dependa dos padrões de um shell interativo. Coloque operações com vários comandos em scripts revisados, com tratamento explícito de erros e versão, e então invoque um único ponto de entrada do script.
Verifique hosts antes que um agente possa alcançá-los
A verificação de host é um problema de inventário, não um prompt que um agente deveria responder. Uma credencial de usuário válida prova ao servidor quem é o cliente. A chave de host do servidor prova ao cliente qual servidor respondeu. Você precisa dos dois.
Nunca use StrictHostKeyChecking=no como correção para automação. A documentação atual do OpenSSH diz que essa configuração pode adicionar novas chaves automaticamente e permitir que uma conexão continue quando uma chave de host mudou, sujeita a restrições. accept-new é melhor porque rejeita chaves alteradas, mas ainda confia na primeira conexão. Para um canal de agente, provisione a confiança antes da execução e use StrictHostKeyChecking=yes.
ssh-keyscan ajuda a coletar chaves públicas de host, mas não as autentica. Seu próprio manual alerta que um invasor de rede pode substituir uma chave e recomenda verificar a saída fora de banda ou usá-la apenas em uma rede confiável. Copiar sua saída ao vivo diretamente para known_hosts transforma uma etapa de verificação em um registro de quem respondeu primeiro.
Obtenha impressões digitais por um plano de controle independente: console de instância em nuvem, registro de criação da imagem, repositório de configuração revisado pelo responsável pelo host ou entrega direta de um administrador. Armazene nome de host, porta, algoritmos de chave de host permitidos, impressões digitais, responsável, ambiente e procedimento de rotação. Revise também aliases e hosts de salto. O destino final pode estar perfeitamente fixado enquanto um host de salto não fixado quebra o caminho de confiança.
Uma verificação de admissão útil compara chaves observadas e aprovadas sem mudar a confiança:
ssh-keyscan -T 5 -t ed25519 host.example > observed.keys
ssh-keygen -lf observed.keys
A saída da impressão digital tem campos para tamanho em bits, impressão digital, rótulo do host e tipo de chave. Uma pessoa ou serviço de inventário confiável compara a impressão digital com o valor fornecido independentemente. Somente após a correspondência a automação deve instalar a entrada de hosts conhecidos. A varredura é evidência para comparar, não evidência em que confiar.
Planeje a rotação antes de impor a fixação. UpdateHostKeys do OpenSSH pode aprender chaves adicionais depois que o servidor foi autenticado com uma chave já confiável, o que ajuda numa rotação gradual. Se usar essa extensão ou distribuir um novo conjunto de known-hosts, defina um período de sobreposição e um caminho de emergência. Uma chave alterada deve parar a execução e produzir um erro de identidade distinto. Ela nunca deve acionar uma repetição genérica, exclusão automática da entrada antiga ou um cartão de aprovação que peça a um revisor apressado para aceitar uma impressão digital sem explicação.
Exija idempotência no limite do efeito
Um comando é seguro para repetir apenas quando repeti-lo após qualquer execução parcial produz o mesmo estado pretendido sem duplicar o efeito. Sintaxe de somente leitura não confere essa propriedade, e um status de saída zero não a prova.
Alguns comandos são naturalmente repetíveis: ler um arquivo fixo, verificar o estado de um serviço ou criar um diretório com mkdir -p sob permissões controladas. Outros precisam de proteções. Acrescentar uma linha com echo ... >> file, enviar uma notificação, criar um usuário com identificador gerado, cobrar uma conta por uma ferramenta local e reiniciar um serviço não são seguros apenas porque o comando de shell é curto.
O conselho usual de «repetir erros SSH transitórios» está errado neste nível. Ele é popular porque reconectar corrige muitas falhas de rede e porque bibliotecas de cliente HTTP normalizam repetições. SSH pode perder a conexão depois que o processo remoto confirma sua mudança, mas antes de o cliente receber o status de saída. Uma repetição automática então repete uma ação concluída.
Leve a segurança de repetição para a operação remota. Dê a cada solicitação mutável um ID de operação estável, gerado antes da aprovação. Armazene esse ID junto ao efeito na mesma transação, quando possível. Se a operação for executada novamente, devolva o resultado registrado em vez de aplicar a mutação outra vez. Quando nenhuma transação cobrir o marcador e o efeito, adicione uma consulta de reconciliação que determine qual lado foi concluído.
Um pequeno script de implantação pode tornar o contrato visível:
#!/bin/sh
set -eu
op_id=$1
release=$2
state_dir=/var/lib/agent-ops
record="$state_dir/$op_id"
test -d "$state_dir" || exit 70
if test -f "$record"; then
cat "$record"
exit 0
fi
current=$(/usr/bin/readlink /srv/app/current || true)
if test "$current" = "/srv/app/releases/$release"; then
/usr/bin/printf '{"operation":"%s","state":"already-current"}\n' "$op_id"
exit 0
fi
test -d "/srv/app/releases/$release" || exit 66
/usr/bin/ln -sfn "/srv/app/releases/$release" /srv/app/current.new
/usr/bin/mv -f /srv/app/current.new /srv/app/current
/usr/bin/printf '{"operation":"%s","state":"changed","release":"%s"}\n' \
"$op_id" "$release" > "$record.tmp"
/usr/bin/mv -f "$record.tmp" "$record"
cat "$record"
Este exemplo não é universalmente atômico. A troca de link simbólico e o registro da operação são duas alterações no sistema de arquivos, portanto uma falha entre elas deixa uma lacuna. A verificação explícita de current reconcilia essa lacuna específica. Sua operação precisa de uma proteção ligada ao próprio efeito, não de um marcador genérico copiado deste script.
Classifique cada comando permitido como somente leitura, convergente, desduplicado ou não repetível. Convergente significa que a execução repetida avança para um estado declarado, como definir um valor de configuração. Desduplicado significa que o lado remoto reconhece o ID da operação. Ações não repetíveis exigem uma consulta de status separada e decisão humana após incerteza. Se o responsável não puder classificar um comando, não o admita.
Mostre ao aprovador o efeito, não o texto de shell
Uma aprovação só ajuda quando o revisor consegue identificar o alvo, a autoridade, o efeito pretendido e a pior consequência plausível antes de agir. O texto bruto do shell é evidência necessária, mas um resumo ruim.
Compare systemctl restart api com uma aprovação que diz: host de produção api-03, usuário remoto deploy, reiniciar o serviço api, conexões ativas podem cair, ID da operação rel-2026-07-24-04, versão do comando restart-service/v2. A segunda descrição oferece ao revisor fatos que ele pode conferir com uma alteração. Ela também expõe contexto ausente. Se o agente não consegue dizer qual host ou serviço afetará, não deveria receber aprovação.
A carga de aprovação deve se vincular à solicitação exata de execução. Inclua host e porta canônicos, impressão digital verificada, conta remota, resumo do comando ou script revisado, argumentos normalizados, diretório de trabalho, adições ao ambiente, timeout, mudança de privilégio solicitada, ID da operação e se a ação é repetível. Faça hash dessa carga e execute apenas o hash aprovado. Caso contrário, um agente pode obter aprovação para um comando e alterar um argumento antes do envio.
Mostre aspas de shell exatamente como estão, mas não obrigue o revisor a executá-las mentalmente. Analise apenas formas de comando que você controla. Se texto arbitrário de shell continuar no escopo, identifique-o como arbitrário e apresente a string inteira sem omissões. Sinalize redirecionamentos, substituição de comando, pipes, execução em segundo plano, sudo, exclusão de arquivos, mudanças de permissões, operações de pacote, controle de serviço e download pela rede. Um sinalizador não é um veredito. Ele indica ao revisor onde as consequências podem se ocultar.
O escopo da aprovação deve ficar mais restrito conforme os efeitos crescem. Uma aprovação de sessão pode ser razoável para sondagens fixas de somente leitura em um inventário aprovado. Uma aprovação por chamada serve para alterações de estado, uso de uma conta remota privilegiada ou comandos cujos argumentos escolhem o alvo. Não deixe uma aprovação inofensiva para uname autorizar silenciosamente uma implantação posterior só porque ambas compartilham uma chave SSH.
Os controles fixos do Sallyport se encaixam bem nessa divisão: sua autorização de sessão identifica um novo processo de agente, enquanto uma chave por chamada pode exigir aprovação a cada uso. O trabalho de projeto importante ainda pertence à solicitação: o cartão precisa revelar o efeito remoto, pois ter um canal aprovado não explica o que um comando fará.
Teste a integridade da aprovação, não apenas a aparência. Mude um byte de um argumento aprovado e confirme que a execução para. Coloque em disputa duas solicitações que reutilizam um ID de operação. Revogue a sessão entre aprovação e envio. Bloqueie o armazenamento de credenciais depois que o cartão aparecer. Cada teste deve terminar em uma negação registrada ou em uma solicitação que precisa ser aprovada novamente, nunca em continuação de melhor esforço.
Modele estado remoto desconhecido como resultado de primeira classe
Desconhecido é um resultado válido sempre que o cliente não consegue provar se o efeito remoto foi concluído. Chamá-lo de falha incentiva repetições. Chamá-lo de sucesso esconde trabalho incompleto.
Considere uma sequência comum. Um agente conecta, inicia um script e o script substitui um arquivo de configuração. A recarga do serviço começa. Nesse momento, o caminho de rede cai. O cliente não recebe nem status de saída nem stdout final. Um timeout local dispara e marca a chamada como falha. O agente repete. A segunda execução vê o novo arquivo, envia outra recarga e talvez sobrescreva o registro de diagnóstico da primeira execução. A chamada original fez trabalho real mesmo que o cliente nunca tenha observado sua conclusão.
A RFC 4254 torna essa ambiguidade esperada. O protocolo transporta saída de comando, status de saída, sinal de saída, EOF e fechamento de canal como mensagens separadas. Ele recomenda devolver status de saída, mas não o garante. Mesmo um fechamento limpo de canal só informa ao cliente sobre o canal, não se um sistema externo chegou ao estado de negócio solicitado.
Defina a máquina de estados antes de lançar:
not_started: conexão, identidade, autenticação ou aprovação falhou antes do envio.started: o lado remoto aceitou o comando, mas ainda não existe resultado terminal.completed: um status terminal e toda a saída limitada chegaram.unknown: o envio pode ter ocorrido, mas o cliente perdeu a prova de conclusão.reconciled: uma consulta independente estabeleceu posteriormente o estado resultante.
Em geral, só not_started é seguro para repetição automática, e até esse rótulo deve vir de um limite confiável. Se os bytes que carregam o comando podem ter chegado ao servidor, use unknown. Um prazo não cancela um processo remoto, a menos que você tenha um protocolo de cancelamento confirmado. Fechar o soquete do cliente não é esse protocolo.
Todo comando mutável precisa de um plano de reconciliação definido antes da aprovação. O plano pode consultar o registro da operação, comparar um identificador de versão implantada, ler o estado do gerenciador de serviços ou pedir ao sistema posterior o ID de operação estável. Execute a reconciliação com uma credencial somente leitura sempre que possível. Preserve a solicitação original, sua saída parcial, timestamps, impressão digital do host e ID da operação para que o acompanhamento responda à pergunta certa.
Defina um orçamento de estado desconhecido. Decida quanto tempo o sistema espera, quem recebe o alerta, quais ações ficam bloqueadas atrás da operação não resolvida e quando uma pessoa assume. Nunca permita que duas operações incertas contra o mesmo recurso disputem entre si. Serialize por recurso ou use um bloqueio remoto com proprietário e política de expiração que sobreviva à desconexão do cliente.
Restrinja a conta remota antes de ampliar os comandos
A prontidão para SSH depende mais da autoridade remota do que da intenção do lado do cliente. Uma tela de aprovação perfeita não compensa uma conta de login capaz de reescrever o host.
Crie uma conta dedicada para o canal do agente. Dê a ela o menor acesso ao sistema de arquivos e as menores permissões de serviço necessárias para as operações admitidas. Evite uma conta geral de administrador. Se elevação for necessária, permita comandos nomeados com caminhos fixos e argumentos controlados. Trate sudo sem restrições, escapes de shell dentro de programas permitidos, diretórios de scripts graváveis e executáveis graváveis como rotas equivalentes para acesso mais amplo.
Restrições de authorized_keys do OpenSSH podem reduzir a exposição de uma credencial. Conforme o projeto, um comando forçado pode encaminhar cada conexão por um despachante, enquanto opções podem desativar pseudo-terminais, encaminhamento de agente, encaminhamento X11 e encaminhamento de portas. A configuração do servidor também pode restringir encaminhamento. Use o manual real do servidor e teste a configuração efetiva, pois uma única inclusão ou bloco match permissivo pode desfazer sua suposição.
Um despachante deve aceitar um pequeno nome de operação e dados, validar ambos e chamar um executável por caminho absoluto sem reconstruir texto arbitrário de shell. Por exemplo, read-release pode não aceitar argumentos, enquanto activate-release aceita um identificador de versão que corresponde a um formato estrito. O canal SSH continua sendo o meio de transporte, mas a superfície remota passa a se parecer mais com uma API definida.
Não encaminhe o agente de autenticação do desenvolvedor para uma sessão autônoma. O encaminhamento de agente permite que o lado remoto peça assinaturas pelo soquete encaminhado enquanto a conexão estiver ativa. Um host remoto comprometido pode não extrair a chave privada, mas pode usar a capacidade de assinatura. Dê ao canal uma credencial dedicada cuja autorização do lado do servidor já seja restrita.
Verifique a propriedade do sistema de arquivos até cada executável e arquivo de configuração. Se a conta restrita puder modificar um diretório pai, substituir o despachante, influenciar um arquivo de inicialização carregado ou antepor um binário por PATH, a lista de permissões é decorativa. Verifique também os interpretadores. Permissão para executar um interpretador amplo costuma significar permissão para fazer tudo que a conta puder fazer.
Mantenha o primeiro conjunto de comandos simples: leituras fixas de inventário, consultas de saúde com saída limitada e uma mutação convergente com caminho de reconciliação testado. Encaminhamento de portas, shells interativos, uploads arbitrários, gerenciamento de pacotes e comandos root livres pertencem a revisões posteriores, se é que pertencem.
Comprove a observabilidade sob truncamento e desconexões
As evidências de auditoria estão prontas quando conseguem reconstruir autorização, envio, identidade remota e resultado observado sem depender do resumo do próprio agente. Os logs devem preservar a incerteza, não apagá-la.
Registre um ID de solicitação e ID de operação estáveis, a identidade do processo ou sessão do agente, a decisão de aprovação, o método do aprovador, hash da carga aprovada, alvo canônico, impressão digital da chave de host, conta remota, hora de início, hora de envio, hora terminal, status ou sinal de saída, contagens de bytes de cada fluxo, indicadores de truncamento e classificação final do estado. Mantenha stdout e stderr separados. Se a política proibir reter saída completa, armazene a parte permitida junto a um resumo e metadados claros de retenção.
Limites de saída exigem dois comportamentos: parar a coleta local e decidir o que ocorre remotamente. Fechar simplesmente o canal após um megabyte pode deixar o processo em execução. Um invólucro remoto pode limitar a saída, enviá-la a um arquivo controlado e informar um resumo, mas esse invólucro também precisa de cotas de disco e limpeza. Teste um comando que nunca fecha stdout, um filho que sobrevive ao pai e um processo que escreve stderr sem parar.
Os logs também devem mostrar o que não ocorreu. Uma incompatibilidade de chave de host, cofre bloqueado, aprovação rejeitada, sessão expirada, solicitação malformada ou comando não permitido deve criar um registro de negação antes de retornar. Caso contrário, operadores veem uma lacuna e não conseguem distinguir um sistema silencioso de uma evasão.
O Sallyport registra execuções de agentes e chamadas individuais em um único log de auditoria criptografado e encadeado por hashes, e sp audit verify verifica a cadeia offline sobre texto cifrado sem chave. Isso fornece ao canal evidência local resistente a adulteração, mas seus IDs de operação remota e resultados de reconciliação ainda precisam aparecer na solicitação e no resultado para que um operador conecte a chamada ao estado da máquina.
Execute injeção de falhas enquanto coleta as evidências que um revisor de incidentes receberia. Mate o cliente antes do envio, imediatamente depois do envio, no meio de stdout e depois que o processo remoto sair, mas antes da conclusão local. Gire a chave de host sem atualizar o inventário. Encha o sistema de arquivos remoto antes de gravar um marcador. Retorne uma saída bem-sucedida com saída estruturada malformada. Em cada caso, faça uma pergunta: um revisor consegue dizer qual autoridade foi usada, o que pode ter mudado e o que precisa acontecer em seguida?
Admita SSH somente depois que os portões passarem
O segundo canal está pronto quando a equipe consegue demonstrar seu comportamento em falhas, não quando um comando no caminho feliz alcança um host de teste. Use um portão escrito, com responsáveis e evidências guardadas.
O registro de admissão deve conter:
- Um contrato de canal que nomeie shell, conta, diretório, ambiente, timeouts, limites de saída e esquema de resultado.
- Um inventário de hosts verificado, com fonte independente de impressões digitais, cobertura de hosts de salto e processo de rotação testado.
- Um catálogo de comandos que classifique o comportamento de repetição e indique a consulta de reconciliação para cada mutação.
- Uma especificação de aprovação vinculada ao host exato, conta, versão do comando, argumentos, privilégio, timeout e ID da operação.
- Resultados de injeção de falhas que comprovem estados desconhecidos, negações, truncamento, revogação e reconstrução de auditoria.
Passe primeiro pelas sondagens somente leitura. Depois admita uma escrita convergente em um ambiente descartável. Desconecte-a em cada limite e reconcilie o resultado. Repita em um host semelhante à produção, com um recurso inofensivo. Revise as evidências com a pessoa responsável por esse host, não apenas com a equipe que criou o gateway do agente.
Mantenha reversão separada de repetição. Uma reversão é uma mutação nova e explícita, com aprovação própria, ID de operação, pré-condições e possível estado desconhecido. Executar automaticamente um comando inverso após um timeout pode danificar uma alteração que na verdade foi concluída corretamente. O sistema precisa estabelecer o estado atual antes de alterá-lo novamente.
Defina critérios de remoção ao lado dos critérios de admissão. Desative uma operação quando o resumo de seu script mudar sem revisão, seu host sair do inventário, a reconciliação deixar de funcionar, a saída se tornar ilimitada ou os operadores não conseguirem explicar um resultado desconhecido. O acesso ao canal não é um certificado permanente de aprovação.
SSH ganha admissão uma operação por vez. Se você não consegue fixar o servidor, descrever o efeito, repeti-lo com segurança, distinguir todos os estados de resultado e reconstruir a chamada depois, o resultado correto da checklist é «não está pronto». Mantenha o canal HTTP somente leitura e corrija o limite ausente antes que um shell remoto transforme uma repetição ambígua em uma segunda alteração de produção.
FAQ
Quando um agente de IA está pronto para acesso SSH?
Um agente está pronto quando a identidade do host está fixada, os comandos têm resultados tipados, as mutações podem ser repetidas com segurança, as aprovações se vinculam ao efeito exato e desconexões produzem um estado desconhecido explícito. Um login de teste bem-sucedido prova apenas conectividade.
SSH somente leitura é seguro o suficiente para habilitar primeiro?
É a etapa inicial certa, mas a conta remota ainda precisa de permissões restritas e saída limitada. Um comando que parece somente leitura pode executar arquivos de inicialização, chamar um binário inesperado pelo PATH ou expor segredos na saída.
A automação SSH deve usar StrictHostKeyChecking no?
Não. Provisione chaves de host verificadas antes da execução e use StrictHostKeyChecking=yes. Desativar a verificação troca um aviso operacional por uma falha de identidade que a automação pode não perceber.
ssh-keyscan pode criar known_hosts com segurança?
ssh-keyscan pode coletar uma chave, mas não consegue autenticar a chave recebida. Compare sua impressão digital com um valor obtido por um canal confiável independente antes de instalá-la.
O código de saída SSH 0 prova que a alteração funcionou?
Isso prova apenas que o status relatado pelo comando remoto foi zero. O comando pode definir sucesso de modo inadequado, um pipeline pode ocultar uma falha anterior ou o estado externo pretendido ainda pode estar incorreto. Portanto, verifique a saída estruturada ou reconcilie o estado.
O que significa o código de saída SSH 255?
O cliente OpenSSH usa 255 ao encontrar um erro e, caso contrário, retorna o status do comando remoto. Como um programa remoto também pode escolher 255, mantenha o estado do transporte separado do status de saída remoto no adaptador.
Quando um comando SSH é idempotente?
Um comando é idempotente quando repeti-lo após qualquer execução parcial produz o mesmo estado pretendido sem duplicar o efeito. Teste o limite do efeito, não a grafia do comando, e use IDs de operação estáveis ou proteções baseadas em estado.
Um agente deve repetir automaticamente um timeout de SSH?
Somente quando o sistema puder provar que o comando nunca começou. Se o envio pode ter ocorrido, marque o resultado como desconhecido e execute uma consulta de reconciliação somente leitura antes de considerar outra mutação.
O que um cartão de aprovação SSH deve mostrar?
Mostre o host canônico, a impressão digital verificada, a conta remota, o efeito pretendido, o comando exato ou a versão do script, os argumentos normalizados, a mudança de privilégio, o timeout e o ID da operação. Vincule a aprovação a essa carga para que nada possa mudar após o clique.
Como as equipes devem testar o acesso SSH de agentes?
Injete falhas antes, durante e depois da execução remota, incluindo alterações de chave de host, excesso de saída, sinais, timeouts e desconexões. As evidências devem informar ao operador o que pode ter mudado e qual ação de reconciliação é segura.