0 XP
Módulo 9 · GitOps com ArgoCD

Segredos em GitOps: External Secrets e SOPS

Avançado 40 min+25 XPExternal Secrets OperatorSOPSSecrets Manager

Objetivos desta aula

  • Escolher estratégia de segredo
  • Configurar External Secrets
  • Encriptar valores com SOPS

O paradoxo do GitOps é claro: tudo em Git, mas segredo não pode ir para Git em texto. Duas soluções dominam. External Secrets Operator mantém o valor em um cofre (AWS Secrets Manager, Vault) e cria o Secret no cluster a partir de uma referência versionável. SOPS encripta o valor no próprio arquivo com chave gerenciada (KMS), permitindo versionar com segurança.

External Secrets costuma ser a melhor escolha quando já existe cofre corporativo: rotação acontece no cofre e o cluster acompanha. SOPS é excelente para times pequenos e para configuração que muda pouco, mantendo o fluxo 100% em Git.

Em qualquer estratégia, valem as mesmas regras: rotação periódica, acesso auditado, escopo mínimo e nenhum segredo em log, em ConfigMap ou em variável impressa por pipeline.

1. O dilema

Tudo vai para o Git — menos senhas em texto claro. Duas saídas: guardar o segredo criptografado no Git (SOPS, Sealed Secrets) ou guardar só uma referência e buscar num cofre (External Secrets Operator).

2. External Secrets Operator

Um SecretStore diz como acessar o cofre (AWS Secrets Manager, Vault, GCP) usando identidade do Pod (IRSA), sem chave fixa. Um ExternalSecret diz qual segredo buscar e cria o Secret do Kubernetes, renovando periodicamente.

3. SOPS com age

O SOPS criptografa só os valores do YAML, mantendo as chaves legíveis para revisar diffs. O ArgoCD descriptografa com um plugin (ou KSOPS) usando a chave privada guardada apenas no cluster.

4. Rotação e vazamento

Com cofre externo, rotacionar é trocar no cofre e esperar o refresh. Se um segredo for commitado em claro: revogue primeiro, depois limpe o histórico — remover o arquivo não basta.

5. Defesa extra

Ative secret scanning no GitHub, hooks como gitleaks no pre-commit e RBAC que impede listar Secrets para a maioria das pessoas.

Na prática

External Secret referenciando o cofre

yaml

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata: { name: aws-secrets }
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        jwt:
          serviceAccountRef: { name: external-secrets }
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata: { name: cloudshop-db }
spec:
  refreshInterval: 1h
  secretStoreRef: { name: aws-secrets, kind: SecretStore }
  target: { name: cloudshop-db, creationPolicy: Owner }
  data:
    - secretKey: password
      remoteRef: { key: cloudshop/db, property: password }

Nota de segurança: A ServiceAccount do operador deve ter permissão apenas nos segredos com prefixo cloudshop/.

SOPS com KMS

bash

sops --encrypt --kms arn:aws:kms:us-east-1:123456789012:key/abc secrets.yaml > secrets.enc.yaml
git add secrets.enc.yaml    # somente o arquivo encriptado
sops --decrypt secrets.enc.yaml | kubectl apply -f -

# validacao: garantir que nada em texto puro entre no repositorio
grep -rIl "password:" overlays/ | xargs -r grep -L "ENC\["

ExternalSecret buscando a senha do banco

yaml

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata: { name: api-db, namespace: cloudshop }
spec:
  refreshInterval: 1h
  secretStoreRef: { name: aws-secrets, kind: ClusterSecretStore }
  target: { name: api-db }              # Secret criado no cluster
  data:
    - secretKey: DB_PASSWORD
      remoteRef: { key: cloudshop/prod/db, property: password }

Nota de segurança: O Git só guarda a referência; o valor nunca sai do cofre em texto claro.

Criptografando com SOPS + age

bash

age-keygen -o key.txt                         # chave privada: nunca no Git
sops --encrypt --age $(grep public key.txt | cut -d: -f2) \
  --encrypted-regex '^(data|stringData)$' secret.yaml > secret.enc.yaml
sops --decrypt secret.enc.yaml | kubectl apply -f -   # só para teste local
gitleaks detect --source .                     # procura segredos vazados

Por que isso importa

Segredo vazado em repositório é o incidente de segurança mais comum e mais evitável do setor.

Erro comum

Commitar Secret em base64 acreditando que base64 é criptografia.

Dica de produção

Adicione um scanner de segredos no CI do repositório GitOps; ele barra o erro humano.

Alerta de segurança

Segredo comitado é comprometido para sempre: rotacione, não apenas remova o arquivo.

Pergunta de entrevista

Como você gerencia segredos em um fluxo GitOps?

Glossário

External Secrets
Operador que sincroniza segredos de um cofre externo para Secrets do cluster.
SOPS
Ferramenta que encripta valores dentro de arquivos YAML/JSON usando KMS ou PGP.
External Secrets Operator
Operador que sincroniza segredos de cofres externos para Secrets do Kubernetes.
SOPS
Ferramenta que criptografa valores em arquivos YAML/JSON mantendo a estrutura legível.
Sealed Secrets
Segredos criptografados com a chave pública de um controller no cluster.

Conexão com o CloudShop

Migrar a senha do banco do CloudShop para o cofre com External Secrets.

Quiz da aula

  1. 1. Base64 em um Secret do Kubernetes oferece:

  2. 2. Uma senha foi commitada em texto claro. Primeiro passo?

  3. 3. No External Secrets, o que fica no Git?

Minhas anotações

Salvo automaticamente neste navegador.

AnteriorPróxima