Um agente de código rodando no seu terminal roda como você. Ele lê o que você lê e usa o que você usa: seus logins de CLIs de nuvem, seus tokens de git e de pacotes, os arquivos .env de todos os repositórios que você já clonou, as chaves de API que você colou em configs de servidores MCP meses atrás. Na maior parte do tempo isso não é problema, porque o agente faz o que você pediu. O prompt injection muda essa conta. Um texto que o agente lê pelo caminho, numa issue, numa página web ou num README, pode convencê-lo a rodar um comando, e tudo o que esse processo alcança passa a estar ao alcance de um atacante.
No trabalho, nossos agentes executam código contra sistemas de clientes a partir de um sandbox onde nada consegue se autenticar. Escrevi sobre esse design em Uma Capability, Não uma Credencial. Algumas semanas depois, fiz a mesma pergunta sobre o meu próprio laptop, onde rodo agentes de código todo dia, e não encontrei nenhuma ferramenta que respondesse. Scanners de segredos são ótimos para dizer se algum segredo foi commitado num repositório. Eu queria saber o que um processo rodando como eu conseguiria usar agora, incluindo credenciais que nenhum repositório jamais viu, como um login de CLI de nuvem ou um token exportado no meu perfil do shell.
Então criei o heldkeys. Você roda ele onde o agente roda, e ele mostra quais chaves estão ao alcance desse agente, o quanto cada uma é perigosa e como diminuir essa lista.
O que ele verifica
Num laptop, o heldkeys lê os lugares onde as credenciais realmente ficam: variáveis de ambiente, as configs das CLIs da AWS, do gcloud, do Azure e do Kubernetes, arquivos e helpers de credenciais do git, o login da CLI do GitHub, tokens de registry do npm, PyPI, cargo e Docker, chaves SSH sem passphrase, arquivos .env do projeto e tokens esquecidos nas configs MCP do Claude Desktop, Claude Code, Cursor, VS Code e outros. Ele classifica cada achado pelo tempo que a credencial continua valendo e se ela consegue alterar coisas, já que um token de longa duração com permissão de escrita é um risco bem maior que uma sessão curta só de leitura.
A visão padrão cabe em uma tela. Ela traz as credenciais para resolver primeiro, uma tabelinha mostrando onde estão as demais, os segredos que aparecem em vários lugares e alguns próximos passos. O resto fica a um --details de distância, ou em JSON, Markdown ou SARIF.
Dentro de um sandbox ou container, o mesmo binário verifica o que o sandbox expõe por dentro, como um socket do Docker montado (que na prática dá root no host), um token de service account do Kubernetes ou um endpoint de metadata de nuvem acessível. O heldkeys preflight transforma isso numa verificação de passa ou falha para o entrypoint, para que um agente nunca suba num sandbox que guarda uma credencial de escrita de longa duração.
Agentes no CI
Acho que o risco mais novo está no GitHub Actions. Times estão colocando agentes de IA em workflows que respondem a comentários de issues e pull requests, e alguns desses workflows entregam ao agente um token de escrita ou um conjunto de segredos do repositório enquanto ele lê texto que qualquer pessoa na internet pode escrever. Algumas das vulnerabilidades em agentes de código deste ano seguiram exatamente esse formato, incluindo agentes que faziam checkout do código de um pull request e depois carregavam a própria configuração de agente do atacante a partir dele.
O heldkeys ci procura essa combinação. Em tempo de execução, ele lista o que o job consegue alcançar: segredos no ambiente, o GITHUB_TOKEN e se o job consegue emitir credenciais de nuvem via OIDC. Ele também lê os arquivos de workflow e aponta passos de agentes que rodam em gatilhos não confiáveis com segredos ou permissões de escrita, agentes trabalhando dentro de um checkout de pull request externo, actions de agentes sem pin de versão e acesso irrestrito ao shell. Ele segue workflows reutilizáveis locais, então um dispatcher que repassa todos os segredos do repositório para um workflow de review é avaliado com os gatilhos e permissões do dispatcher. Para segurança de workflows em geral, o zizmor já faz um ótimo trabalho, então o heldkeys só tem regras para passos de agentes.
Rodando na minha própria máquina
Rodei primeiro no meu próprio laptop. Ele encontrou o de sempre, aquilo que vai se acumulando com os anos: um arquivo antigo de credenciais do git em texto puro, um token exportado no meu perfil do shell, chaves SSH sem passphrase. Eu não teria listado nenhum desses itens se você me perguntasse, e qualquer agente que eu iniciasse poderia usá-los. A limpeza levou uns vinte minutos. O git agora usa o keychain do sistema, o token de pacotes mora no keychain e só é carregado dentro dos projetos que precisam dele, e as chaves ganharam passphrase.
O dia do lançamento teve uma pequena ironia. A push protection do GitHub bloqueou o primeiro push do repositório porque as fixtures de teste têm tokens falsos do Slack. Uma ferramenta que procura credenciais precisa de dados de teste com cara de credencial, e foi bom ver a plataforma pegar isso.
Decisões de design
Uma ferramenta que lê todas as credenciais da sua máquina precisa conquistar confiança. Os valores só aparecem como fingerprints curtos, e apenas para formatos de token cujo prefixo é público; um teste passa todas as fixtures por todos os formatos de saída e falha se qualquer pedaço de um segredo falso aparecer. Não há telemetria, nem checagem de atualização, nem chamada aos provedores por trás das suas credenciais, e o heldkeys não escreve nada na sua máquina. Tudo o que ele escaneia é tratado como hostil, porque no CI ele lê arquivos de pull requests escritos por desconhecidos. A saída é sanitizada para que um workflow malicioso não consiga injetar sequências de escape no terminal, anotações falsas no log ou links no resumo do job, e o parsing tem limites para que um arquivo pequeno e malicioso não esgote memória nem CPU.
Ele é escrito em Rust e distribuído como um único binário, estático no Linux, então funciona em qualquer container. Algumas coisas ficam fora do alcance dele: sessões do navegador, segredos que só existem dentro do keychain do sistema operacional e qualquer coisa no histórico do git, onde o gitleaks e o TruffleHog são as ferramentas certas. O threat model cobre o resto.
Experimente
brew install hugomn/tap/heldkeys
heldkeys
Também tem um script de instalação de uma linha, binários prontos com proveniência, cargo install heldkeys e uma GitHub Action com saída SARIF para code scanning. Se você rodar, eu adoraria saber o que te surpreendeu e quais lugares de credenciais ele deveria aprender a verificar.