Como já discuti anteriormente no post sobre secret management no macOS e no Linux, o grande problema de gerenciar chaves e tokens não é a criptografia em si, mas sim reduzir o vazamento acidental sem transformar a rotina do sysadmin num inferno burocrático. Nos últimos anos, porém, uma dupla de ferramentas ganhou espaço e mudou completamente essa dinâmica: o Mozilla SOPS e o age. Juntos, eles permitem uma abordagem declarativa (GitOps-friendly), extremamente segura e com fricção quase zero. Este post é uma análise detalhada sobre o funcionamento dessas ferramentas e como integrá-las de forma prática no seu dia a dia.

age: Criptografia moderna para a vida real#

O age (criado por Filippo Valsorda) foi projetado com uma premissa simples: ser uma ferramenta de criptografia de arquivos moderna, segura e, acima de tudo, descomplicada. Ele foi feito para substituir o GPG nos casos de uso cotidianos de infraestrutura.

Enquanto o GPG é um monólito com décadas de legado e suporte a dezenas de algoritmos obsoletos, o age usa criptografia de ponta por padrão (como X25519 e ChaCha20-Poly1305) e não tenta gerenciar sua identidade. Ele não tem “trust networks” ou base de dados local de chaves.

Uma chave do age é simplesmente um arquivo de texto contendo duas strings:

  • A chave pública (que começa com age1...), usada para criptografar.
  • A chave privada (que começa com AGE-SECRET-KEY-1...), usada para descriptografar.

O age na prática#

Instalar o age é trivial em qualquer sistema. No macOS você usa brew install age, e na maioria das distribuições Linux ele já está nos repositórios oficiais (apt install age).

Para gerar um par de chaves, basta rodar:

age-keygen -o key.txt

O arquivo gerado será parecido com isto:

# created: 2026-05-26T07:15:00-03:00
# public key: age1y3d8q2u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqyv2pns
AGE-SECRET-KEY-1R4X2QYLWMVPTQYP...

Criptografar um arquivo usando a chave pública é direto:

age -r age1y3d8q2u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqyv2pns -o segredos.enc segredos.txt

E para descriptografar usando a chave privada:

age -d -i key.txt segredos.enc

É apenas isso. Sem demônios em background, sem chaves expiradas travando seu script, sem chaves públicas importadas em um banco de dados local. Apenas arquivos de texto e fluxos de entrada e saída.

Mozilla SOPS: Criptografia parcial e inteligente#

Embora o age resolva o problema da criptografia de arquivos de forma brilhante, ele ainda opera no nível do arquivo inteiro. Se você tem um arquivo YAML de configuração com 50 linhas e apenas duas delas são segredos (como a senha do banco de dados), criptografar o arquivo inteiro com age traz dois problemas clássicos no controle de versão:

  1. Você perde a visibilidade do que mudou no Git (o diff vira apenas um bloco binário opaco).
  2. Resolver conflitos de merge em arquivos binários criptografados é virtualmente impossível.

É aqui que entra o Mozilla SOPS (Secrets Operations).

O SOPS é um editor de arquivos criptografados que suporta YAML, JSON, TOML, arquivos .env e binários. A sua grande sacada é a criptografia parcial: ele analisa a estrutura do seu arquivo e criptografa apenas os valores, mantendo as chaves estruturais em texto claro.

O SOPS em ação#

Imagine que você tem o seguinte arquivo de configuração (secrets.yaml):

database:
  host: db.internal
  username: app_user
  password: "minha-senha-super-secreta"
api:
  token: "sk_live_abcdef123456"

Ao rodar o comando do SOPS configurado para usar a sua chave do age:

sops --encrypt --age age1y3d8q2u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqyv2pns secrets.yaml > secrets.enc.yaml

O arquivo secrets.enc.yaml resultante terá esta cara:

database:
  host: db.internal
  username: app_user
  password: ENC[AES256_GCM,data:lTqgB4e5aY1G8pQ=,iv:...,tag:...]
api:
  token: ENC[AES256_GCM,data:2u7gB4a...,iv:...,tag:...]
sops:
  age:
    - recipient: age1y3d8q2u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqyv2pns
      enc: |
        -----BEGIN AGE ENCRYPTED FILE-----
        ...
        -----END AGE ENCRYPTED FILE-----
  lastmodified: "2026-05-26T07:22:00Z"
  version: 3.9.0

Repare no quanto isso é elegante:

  • As chaves database.host e database.username permanecem legíveis. Qualquer um que ler o repositório sabe que o host é db.internal.
  • Apenas os valores confidenciais (password e token) foram criptografados com AES-256-GCM.
  • Os metadados sobre como descriptografar o arquivo (incluindo a chave pública do destinatário) ficam anexados na chave sops.

No Git, se você alterar o host do banco de dados, o diff mostrará exatamente essa linha mudando. Se você rotacionar a senha, apenas a linha do valor criptografado mudará. O diff continua limpo, legível e útil.

Além disso, editar o arquivo é extremamente transparente. Se você definir a variável de ambiente SOPS_AGE_KEY_FILE=/path/to/key.txt e rodar:

sops secrets.enc.yaml

O SOPS lerá a sua chave privada, descriptografará o arquivo temporariamente na memória, abrirá o seu editor padrão (definido na variável $EDITOR), esperará você fazer as alterações, re-criptografará o arquivo e o salvará de volta no disco assim que o editor for fechado. A chave privada nunca toca o arquivo salvo e o texto claro nunca toca o disco.

O poder do arquivo .sops.yaml#

Ficar passando chaves públicas na linha de comando toda vez que você criptografa um arquivo é inviável e propício a erros. O SOPS resolve isso através de um arquivo de configuração declarativo colocado na raiz do seu repositório: o .sops.yaml.

Este arquivo define regras sobre quais chaves devem criptografar quais arquivos baseando-se em expressões regulares.

Aqui está um exemplo real de infraestrutura:

creation_rules:
  # Regra para segredos de produção
  - path_regex: secrets/production/.*\.yaml$
    key_groups:
      - age:
          - age1y3d8q2u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqyv2pns # Dev Principal (Janio)
          - age1r78k4u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlq928asl0212 # Chave do Servidor de Prod
          - age1backup9u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqkey00 # Chave de Backup Fria

  # Regra para segredos de staging/desenvolvimento
  - path_regex: secrets/staging/.*\.yaml$
    key_groups:
      - age:
          - age1y3d8q2u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqyv2pns # Dev Principal
          - age1dev01u9vx8zux5mshq8387hws55v7pyll6zdfp4slx2p8nlyspqyvdev01 # Chave do time de desenvolvimento

Com essa estrutura, quando qualquer pessoa do time executa sops secrets/production/app.yaml, o SOPS lê a configuração automaticamente e criptografa o arquivo de forma que qualquer um dos três destinatários listados na regra de produção consiga descriptografá-lo usando sua respectiva chave privada do age.

Isso elimina a necessidade de compartilhar chaves privadas. O desenvolvedor usa a chave dele, o servidor usa a chave dele, e o backup usa a chave dele.

Adicionando novas máquinas e rotacionando chaves#

Se você precisar autorizar um novo servidor a ler os segredos de produção, o fluxo é simples:

  1. Gere uma chave age no novo servidor.
  2. Pegue a chave pública e adicione-a na lista de destinatários em .sops.yaml.
  3. No seu computador de administrador, aplique a nova configuração aos arquivos existentes rodando:
sops updatekeys secrets/production/app.yaml

O SOPS vai descriptografar o arquivo usando a sua chave privada e re-criptografá-lo adicionando o novo servidor à lista de destinatários. Em seguida, basta commitar as mudanças no Git.

Como consumir os segredos na prática (Sem fricção)#

Embora o ecossistema sops + age seja incrivelmente robusto para armazenamento, você ainda precisa ler esses segredos para utilizá-los nos seus scripts, deploys e aplicações. A boa notícia é que o SOPS oferece várias maneiras de fazer isso com fricção mínima.

1. Injetando segredos no ambiente via CLI (sops exec-env)#

Se você tem um script, container ou aplicação que espera encontrar as chaves de API e senhas como variáveis de ambiente tradicionais, você não precisa mantê-las salvas em arquivos .env em texto puro. O SOPS possui um comando específico para descriptografar os segredos em memória e injetá-los no processo da sua aplicação:

sops exec-env secrets.enc.yaml 'npm run start'

O comando npm run start será iniciado com acesso a todas as variáveis definidas no arquivo descriptografado, mas assim que o processo terminar, essas variáveis deixam de existir. Nenhum segredo foi persistido em texto claro no disco.

2. Lendo segredos estruturados em scripts de Shell#

Se você precisa extrair apenas um valor específico de dentro de um arquivo YAML criptografado no seu script de automação, você pode combinar o SOPS com o utilitário yq (ou o próprio parser interno do SOPS):

# Usando o extrator nativo do SOPS
DB_PASS=$(sops -d --extract '["database"]["password"]' secrets.enc.yaml)

Isso é ideal para scripts de backup ou deploys automatizados via SSH, permitindo ler exatamente o segredo necessário na hora do uso.

3. Integração direta no seu código (Python)#

Em linguagens de programação, você pode ler os arquivos criptografados do SOPS invocando o binário via subprocesso de forma limpa, retornando um dicionário estruturado diretamente em memória.

Aqui está um helper simples em Python para carregar segredos sem nunca tocá-los no disco em formato legível:

import json
import subprocess

def load_sops_secrets(filepath: str) -> dict:
    # Decodifica o arquivo diretamente na memória em formato JSON
    result = subprocess.run(
        ["sops", "-d", "--output-type", "json", filepath],
        capture_output=True,
        text=True,
        check=True
    )
    return json.loads(result.stdout)

# Uso prático
secrets = load_sops_secrets("secrets.enc.yaml")
db_password = secrets["database"]["password"]

Essa abordagem garante que mesmo se o servidor for comprometido e o disco for copiado, os segredos continuarão seguros (já que a chave do age pode estar isolada sob permissões restritas em /etc/ ou apenas carregada no agent do servidor).

Conclusão: Segurança real é aquela que você realmente usa#

Uma das maiores lições na administração de sistemas é que a segurança é inversamente proporcional à fricção. Se um método de segurança exige 10 passos manuais complexos, as pessoas vão encontrar um atalho — e esse atalho geralmente é uma senha em plaintext em um arquivo desprotegido.

A combinação de SOPS + age brilha porque ela remove o “teatro de segurança”. Ela permite que você mantenha uma infraestrutura 100% declarativa, versionada e segura no Git, sem precisar gerenciar chaves GPG complexas ou provisionar servidores de segredos pesados para ambientes pequenos e médios.

Quando você integra essa fundação na sua rotina de automação, o gerenciamento de segredos deixa de ser um peso operacional para se tornar uma parte natural, fluida e transparente do desenvolvimento.

E você? Como gerencia os segredos na sua infraestrutura hoje? Já deu uma chance para o age ou ainda sofre com chaves GPG? Compartilhe sua experiência nos comentários abaixo.