TL;DR — Resumo Rápido

SOPS criptografa valores em YAML/JSON mantendo chaves legíveis. Guia: age, KMS, rotação de chaves, CI/CD, Kubernetes e integração GitOps com ArgoCD.

Mozilla SOPS (Secrets OPerationS) resolve um dos problemas mais difíceis do GitOps: como armazenar segredos no controle de versão sem expô-los. Ao contrário de ferramentas que criptografam arquivos inteiros, SOPS criptografa apenas os valores em arquivos YAML, JSON, ENV e INI — mantendo as chaves em texto simples para que os diffs continuem legíveis e as revisões de código façam sentido.

Por Que SOPS? O Problema dos Segredos no Git

Fazer commit de segredos em texto simples no Git é um incidente de segurança esperando para acontecer:

  • Apenas variáveis de ambiente — Funciona em runtime mas não versiona nem audita mudanças em segredos.
  • Vault / External Secrets — Poderoso mas requer infraestrutura e acesso online no deploy.
  • git-crypt — Criptografa arquivos inteiros; os diffs tornam-se blobs binários e inúteis.
  • SOPS — Criptografa apenas valores. As chaves permanecem em texto simples. Arquivos fazem diff normalmente.

Um arquivo criptografado com SOPS é assim:

database:
    password: ENC[AES256_GCM,data:abc123...,iv:...,tag:...,type:str]
    host: db.example.com    # ← não criptografado, não é segredo

Instalação

# macOS
brew install sops age

# Ubuntu/Debian
apt install age
wget https://github.com/getsops/sops/releases/latest/download/sops-v3.x.x.linux.amd64 \
  -O /usr/local/bin/sops && chmod +x /usr/local/bin/sops

Backends de Criptografia

BackendMelhor ParaInfraestrutura Necessária
agePadrão moderno simplesNenhuma
PGP/GPGLegado, amplamente suportadoKeyring GPG
AWS KMSEquipes nativas AWSConta AWS + IAM
GCP KMSEquipes nativas GCPProjeto GCP
Azure Key VaultAmbientes Azure/MicrosoftAssinatura Azure
HashiCorp VaultMulti-cloud, on-premCluster Vault

Para novos projetos, age é o padrão recomendado.


age: Aprofundamento

# Gerar um par de chaves
age-keygen -o ~/.config/sops/age/keys.txt
# Public key: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Definir variável de ambiente
export SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt

# Permissões corretas (SOPS rejeita arquivos legíveis por outros usuários)
chmod 600 ~/.config/sops/age/keys.txt

age também suporta chaves SSH como destinatários, útil se sua equipe já tem chaves SSH.


Configuração do .sops.yaml

creation_rules:
  - path_regex: secrets/.*\.yaml$
    age: >-
      age1alice1111111111111111111111111111111111111111111111111111111,
      age1bob2222222222222222222222222222222222222222222222222222222222

  - path_regex: k8s/.*secret.*\.yaml$
    kms: "arn:aws:kms:us-east-1:123456789:key/mrk-abc123"

Grupos de chaves e limiar de Shamir para exigir M de N partes para descriptografar:

creation_rules:
  - path_regex: critical/.*
    key_groups:
      - age:
          - age1alice...
          - age1bob...
      - kms:
          - arn: "arn:aws:kms:us-east-1:123456789:key/mrk-abc123"
    shamir_threshold: 2

Criptografar e Editar Arquivos

# Criptografar para um novo arquivo
sops --encrypt secrets.yaml > secrets.enc.yaml

# Abrir no editor (descriptografa, edita, recriptografa ao salvar)
sops secrets.enc.yaml

# Descriptografar para stdout
sops --decrypt secrets.enc.yaml

# Injetar como variáveis de ambiente
sops exec-env secrets.enc.yaml 'docker-compose up'

Rotação de Chaves

# 1. Adicionar nova chave, remover antiga do .sops.yaml
# 2. Recriptografar arquivos afetados
sops updatekeys --yes secrets/db.yaml

# 3. Verificar que a chave antiga não funciona mais
SOPS_AGE_KEY="chave_privada_antiga" sops --decrypt secrets/db.yaml
# Deve falhar: "could not decrypt data key"

Integração com CI/CD e Kubernetes

GitHub Actions:

- name: Descriptografar segredos
  env:
    SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
  run: sops --decrypt k8s/secrets.enc.yaml | kubectl apply -f -

Workflow para Kubernetes:

kubectl create secret generic db-creds \
  --from-literal=password=supersecret \
  --dry-run=client -o yaml > k8s/db-secret.yaml
sops --encrypt --in-place k8s/db-secret.yaml
git add k8s/db-secret.yaml && git commit -m "Adicionar segredo db criptografado"

KSOPS para ArgoCD e o provedor nativo do Flux permitem descriptografia automática no deploy.


SOPS vs Alternativas

FerramentaCriptografaDiffableInfra NecessáriaGitOps
SOPSApenas valoresSimOpcional (age)Excelente
Sealed SecretsSecret k8s inteiroNãoControladorApenas Kubernetes
External SecretsValores em runtimeN/AVault/KMSSim, apenas online
git-cryptArquivos inteirosNãoGPG keyringLimitado
BlackBoxArquivos inteirosNãoPGP keyringLimitado

Armadilhas e Casos Especiais

  • Nunca faça commit da chave privada — Apenas a chave pública vai no .sops.yaml.
  • .sops.yaml deve estar na raiz do repositório — Ou use --config caminho/.sops.yaml.
  • Permissões do arquivo de chave age — SOPS rejeita um keys.txt legível por outros usuários. Use chmod 600.
  • O limiar de Shamir deve ser atendido — Se KMS estiver indisponível e shamir_threshold: 2, precisa de 2 detentores de chaves age simultaneamente.

Resumo

  • SOPS criptografa valores, não chaves — Arquivos continuam comparáveis e auditáveis no Git.
  • age é o padrão moderno — Sem infraestrutura, funciona offline, suporta múltiplos destinatários.
  • .sops.yaml creation_rules — Mapeie padrões de caminho para chaves com grupos e limiar Shamir.
  • Suporte nativo para Kubernetes — KSOPS para ArgoCD, provedor nativo para Flux.

Artigos Relacionados