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

Backend Melhor Para Infraestrutura Necessária
age Padrão moderno simples Nenhuma
PGP/GPG Legado, amplamente suportado Keyring GPG
AWS KMS Equipes nativas AWS Conta AWS + IAM
GCP KMS Equipes nativas GCP Projeto GCP
Azure Key Vault Ambientes Azure/Microsoft Assinatura Azure
HashiCorp Vault Multi-cloud, on-prem Cluster 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

Ferramenta Criptografa Diffable Infra Necessária GitOps
SOPS Apenas valores Sim Opcional (age) Excelente
Sealed Secrets Secret k8s inteiro Não Controlador Apenas Kubernetes
External Secrets Valores em runtime N/A Vault/KMS Sim, apenas online
git-crypt Arquivos inteiros Não GPG keyring Limitado
BlackBox Arquivos inteiros Não PGP keyring Limitado

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