Precisamos ser cada vez mais cuidadosos com o que armazenamos em nossos discos.

Só em 2025, houve pelo menos meia dúzia de campanhas explorando soluções de software altamente difundidas para exfiltrar dados sensíveis em larga escala. Alguns desses eventos até mesmo aproveitaram agentes de IA instalados nas máquinas das pessoas para ajudar a localizar e extrair informações sensíveis como tokens, carteiras de criptomoedas e chaves de service accounts.

Mesmo que você seja cuidadoso(a) com essas coisas, é possível – provável até – que você tenha pelo menos alguns tokens ou secrets espalhados em plain-text no seu sistema.1

Infelizmente, muitas ferramentas CLI ainda dependem de – ou pelo menos encorajam em guias estilo “Getting Started” – práticas inseguras, como armazenar tokens e secrets em arquivos de configuração em plain-text e passá-los como argumentos de linha de comando.

O Keyring do SO é uma Opção Viável?

Se você usa Linux com um Ambiente de Desktop completo como GNOME, é provável que você já tenha uma implementação do Secret Service instalada, que você pode interagir via utilitário secret-tool:

1
2
3
4
5
6
7
8
# Armazenando um secret no keyring do sistema:
secret-tool store --label="Descrição do Secret" [[atributo] [valor] ...]

# Recuperando o secret:
secret-tool lookup [atributo] [valor]

# Deletando o secret:
secret-tool clear [atributo] [valor]

Embora isso possa atender alguns casos de uso básicos, as opções de persistência de dados para o keyring do sistema operacional são limitadas, então você deve usá-lo apenas para secrets não-críticos e de curta duração.

A keyring também costuma ficar destravada pela duração da sessão do usuário, tornando-a uma opção menos recomendada para dados mais sensíveis.

Gerenciadores de Senhas

Para secrets críticos e/ou de longa duração, é recomendado o uso de uma solução adequada de gerenciador de senhas.

Soluções como 1Password ou Bitwarden funcionariam bem (ambos fornecem ferramentas CLI para interagir com seus cofres), mas eu passei a preferir opções mais leves como GNU Pass, pelo menos para tokens e secrets que são principalmente acessados via terminal.

Lidando Com Variáveis de Ambiente

Algumas pessoas simplesmente dão export em seus tokens no ~/.bashrc e seguem em frente. Esta não é uma abordagem recomendada para informações sensíveis, pois essas variáveis seriam expostas indiscriminadamente a todos os processos do usuário.

O mesmo se aplica a outros secrets armazenados em arquivos plain-text no seu disco. Qualquer processo que você iniciar poderia simplesmente escanear seus arquivos, descobrir informações sensíveis e comprometê-las. Isso é cada vez mais uma preocupação nos dias de hoje com o advento de ferramentas de IA que ainda carecem de sandboxing adequado e controles de segurança.

Resolvendo com GoPass

GoPass é uma reimplementação do GNU Pass em Go com alguns extras.

Um desses extras é o subcomando gopass env. Suponha que você tenha os seguintes secrets:

Caminho do secret Valor
keys/aws/AWS_ACCESS_KEY_ID AKIA..
keys/aws/AWS_SECRET_ACCESS_KEY ...

Você pode executar um comando com essas variáveis definidas com gopass env keys/aws -- aws s3 ls.

Só com este recurso, reduzimos bastante a necessidade de secrets armazenados em plain-text arquivos de configuração, já que a maioria das ferramentas permite que você passe credenciais via variáveis de ambiente como alternativa.

No entanto, essa implementação não cobre todas as minhas necessidades para consumir secrets no terminal. Por exemplo, não é possível executar um comando com secrets de múltiplos prefixos diferentes (digamos, um token do GitHub + credenciais AWS), a menos que você organize suas senhas de uma forma específica, possivelmente duplicando arquivos ou criando symlinks.

Meu Novo Jeito (Com GNU Pass)

Depois de ler a página principal do GNU Pass recentemente, me deparei com uma seção Extensions for pass. Usei GNU Pass por muitos anos e não sabia que ele podia ser estendido assim!

Então decidi pedir ao meu novo melhor amigo Claude Code para criar uma extensão que funcionasse como o subcomando gopass env, mas com mais opções para compor secrets.

A versão completa e atualizada desse script pode ser encontrada aqui, mas a API se parece com isso:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env bash
cmd_env_usage() {
    cat <<-_EOF
Usage:
    $PROGRAM env secret-path [secret-path2 ...] -- [command] [args...]
        Decrypt the secrets at the specified paths, export their contents as
        environment variables, and execute the command + args with those variables set.
        If multiple secrets define the same variable, later secrets take precedence.

        Secret paths can be either:
        - Individual secret files (containing KEY=VALUE pairs)
        - Directories ending with '/' (will recursively decrypt all secrets within,
          using the secret filename as the variable name)

Examples:
    $PROGRAM env /env/infra-keys -- terraform init
    $PROGRAM env /env/common /env/production -- aws s3 ls
    $PROGRAM env secret/app/ -- node server.js
    $PROGRAM env secret/app/ /env/common -- ./run.sh
_EOF
}

Você pode usar isso colocando este arquivo em /usr/lib/password-store/extensions ou no diretório apropriado à sua distribuição.2

Considerações de Segurança

Essa abordagem pode ter suas próprias considerações de segurança. Em outras palavras, não me siga cegamente, eu posso não saber o que estou fazendo. 😄

Algumas coisas que consigo pensar:

  1. Como qualquer solução baseada em variáveis de ambiente, as variáveis de ambiente para os processos lançados ainda podem ser acessadas via /proc/<pid>/environ e via o comando ps e.
  2. Variáveis exportadas estão disponíveis para processos filhos, não apenas o processo original lançado pelo script.

Abordagens Alternativas

Blog do Linus Heckemann fornece uma abordagem alternativa e mais segura por não depender de variáveis de ambiente, o que é claro pode ser mais ou menos aplicável dependendo do seu fluxo de trabalho e das ferramentas envolvidas.

Um truque particularmente interessante é o uso das capacidades de process substitution suportadas por muitos dos shells modernos, incluindo bash, que casa bem com ferramentas como curl e vault:

1
2
3
4
5
6
# Busca my-secret do GNU Pass e armazena no Hashicorp Vault:
vault write secret/my-secret value=@<(pass my-secret)

# Busca chave do GNU Pass e usa como Bearer token em uma requisição POST:
curl -X POST -H @<(echo "Authorization: Bearer $(pass api-keys/my-app)") \
    https://api.my-app.xyz/data

Os secrets extraídos do GNU pass nos comandos anteriores não apareceriam em lugares comuns como /proc/<PID>/environ e /proc/<PID>/cmdline, tornando esta uma opção muito boa para tarefas mais sensíveis.

É claro que você também pode aproveitar Aliases ou Funções do Bash para abstrair os detalhes sobre como secrets são injetados nos seus comandos mais frequentes.

Chaves SSH

Outro tipo comum de secret são arquivos com suas chaves SSH.

Uma recomendação seria usar um token físico como o YubiKey para isso, mantendo o material da chave privada seguro, o que significa que você não precisa mais manter suas chaves SSH no seu sistema de arquivos. Você também pode configurar o token para exigir confirmação de “toque” para diferentes operações, como assinatura, criptografia ou autenticação, dependendo dos seus requisitos de segurança e conveniência.

Depois de configurar o gpg-agent para também atuar como o agente SSH, você pode usar ssh-add -L para exibir a chave pública (que você pode então adicionar ao ~/.ssh/authorized_keys nos seus servidores), e o ssh deve encaminhar requisições de autenticação para o agente GPG.

Se você escolher esse caminho, eu recomendo fortemente dar uma olhada no Guia YubiKey do drduh.

Outra opção seria aproveitar os recursos do seu próprio gerenciador de senhas. Bitwarden (aqui) e 1Password (aqui), por exemplo, permitem que você armazene suas chaves públicas e privadas no próprio gerenciador de senhas e então permita acesso a elas via implementações customizadas de agente SSH que você pode integrar ao seu sistema.

Pra Fechar

A ideia deste post é apenas mostrar como eu faço. Pode ou não funcionar para você, e definitivamente não é a única maneira de fazer, então sinta-se livre para experimentar e escolher o que funciona melhor para você considerando seus requisitos de segurança!


  1. Você pode usar alguma ferramenta como TruffleHog para escanear seus arquivos. ↩︎

  2. Embora possível, eu não aconselho armazenar extensões do GNU Pass no seu $HOME, pois alguma ferramenta maliciosa poderia injetar comportamento indesejado nas suas extensões logo após seus secrets serem descriptografados. ↩︎