Secrets management externo: Vault, Sealed Secrets ou External Secrets
1. Por que Secrets Management Externo no Kubernetes?
1.1. Limitações do Secrets nativo do Kubernetes
O recurso Secret nativo do Kubernetes é frequentemente mal compreendido como uma solução segura. Na realidade, ele apenas codifica dados em base64 — não criptografa. Qualquer pessoa com acesso ao etcd ou permissão get no namespace consegue ler os valores. Além disso, não há rotação automática de segredos, nem auditoria de acesso granular. Em clusters multi-tenant, a exposição acidental de segredos em logs ou manifests versionados no Git é um risco constante.
1.2. Requisitos de segurança e compliance
Normas como GDPR, HIPAA e PCI-DSS exigem criptografia em repouso, rotação periódica e logs de acesso a dados sensíveis. O Secrets nativo falha em todos esses pontos. Ferramentas externas preenchem essas lacunas com criptografia forte, políticas de acesso e integração com sistemas de auditoria.
1.3. Visão geral da arquitetura
Três arquiteturas dominam o cenário:
- Sidecar: um container auxiliar injeta segredos no pod (ex: Vault Agent Injector)
- Operador: um controller Kubernetes reconcilia CRDs para sincronizar segredos (ex: External Secrets Operator)
- Controller nativo: um operador que decripta segredos selados no cluster (ex: Sealed Secrets)
2. HashiCorp Vault: O Padrão Ouro para Segredos
2.1. Conceitos fundamentais
Vault opera com caminhos lógicos (secret/data/myapp), políticas HCL que definem permissões de leitura/escrita, e tokens de curta duração. A autenticação Kubernetes usa o ServiceAccount do pod para gerar tokens temporários, eliminando a necessidade de credenciais estáticas.
2.2. Integração com Kubernetes
O Vault Agent Injector (sidecar) intercepta a criação de pods e injeta um container Vault Agent que renderiza templates de configuração com segredos. Alternativamente, o CSI Provider monta segredos como volumes efêmeros, ideais para workloads que não suportam injeção via variáveis de ambiente.
2.3. Prós e Contras
Prós: rotação dinâmica de segredos (bancos de dados, certificados TLS), audit logging completo, suporte multi-cloud e on-premises. Contras: complexidade operacional elevada (manutenção do cluster Vault, unseal keys, HA), curva de aprendizado íngreme, custo de infraestrutura adicional.
3. Sealed Secrets: Criptografia Git-Nativa com Bitnami
3.1. Funcionamento
Um controller no cluster possui um par de chaves RSA. O cliente kubeseal usa a chave pública para criptografar um Secret em um SealedSecret — um recurso Kubernetes que pode ser versionado no Git com segurança. Apenas o controller, com a chave privada, consegue decriptá-lo.
3.2. Fluxo de trabalho
# 1. Criar um Secret comum
kubectl create secret generic mysecret --from-literal=password=supersecret -n myapp --dry-run=client -o yaml > secret.yaml
# 2. Selar com a chave pública do cluster
kubeseal --format yaml < secret.yaml > sealed-secret.yaml
# 3. Commit do SealedSecret no Git
git add sealed-secret.yaml && git commit -m "Add sealed secret"
# 4. O controller no cluster decripta automaticamente e cria o Secret
kubectl apply -f sealed-secret.yaml
3.3. Casos de uso
Ideal para ambientes GitOps puros (ArgoCD, Flux) onde todo o estado deve estar no repositório. Funciona offline, sem dependência de provedores externos. Excelente para dev/test e clusters pequenos/médios.
4. External Secrets Operator: Ponte para Provedores de Nuvem
4.1. Arquitetura
O operador introduz dois CRDs principais:
- SecretStore: configura a conexão com o provedor externo (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, Vault)
- ExternalSecret: mapeia segredos do provedor para Secrets Kubernetes
O operador reconcilia continuamente, sincronizando alterações no provedor externo para o cluster.
4.2. Exemplo de configuração
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets-store
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
secretRef:
accessKeyIDSecretRef:
name: aws-creds
key: access-key
secretAccessKeySecretRef:
name: aws-creds
key: secret-key
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: myapp-secret
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-store
kind: SecretStore
target:
name: myapp-secret
data:
- secretKey: db_password
remoteRef:
key: /prod/myapp/database
property: password
4.3. Vantagens
Sincronização automática com polling configurável, rotação centralizada no provedor, integração nativa com GitOps (o ExternalSecret é versionado, não o valor). Suporta múltiplos provedores simultaneamente.
5. Comparação Técnica e Critérios de Escolha
5.1. Matriz de decisão
| Critério | Vault | Sealed Secrets | External Secrets |
|---|---|---|---|
| Criptografia | Forte | Forte | Forte (provedor) |
| Rotação automática | Sim | Não | Sim (polling) |
| GitOps nativo | Parcial | Sim | Sim |
| Latência de injeção | Baixa | Zero | Média (polling) |
| Complexidade operacional | Alta | Baixa | Média |
| Custo de infraestrutura | Alto | Baixo | Médio |
5.2. Cenários típicos
- Startup / Projeto pessoal: Sealed Secrets — simples, sem dependências externas
- Enterprise / Regulamentado: Vault — compliance, auditoria, rotação dinâmica
- Multi-cloud / Híbrido: External Secrets — unifica provedores de nuvem
6. Implementação Prática com Exemplos
6.1. Exemplo 1: Sealed Secrets com ArgoCD
# Instalar controller
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm install sealed-secrets sealed-secrets/sealed-secrets -n kube-system
# Selar segredo para produção
kubeseal --controller-namespace kube-system \
--controller-name sealed-secrets \
--format yaml < secret-prod.yaml > sealed-prod.yaml
# Aplicar via ArgoCD (o Application aponta para o repositório Git)
kubectl apply -f sealed-prod.yaml
6.2. Exemplo 2: External Secrets com AWS Secrets Manager
# Instalar operador
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets
# Configurar SecretStore (assumindo credenciais AWS em secret)
cat <<EOF | kubectl apply -f -
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-store
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
secretRef:
accessKeyIDSecretRef:
name: aws-creds
key: access-key
secretAccessKeySecretRef:
name: aws-creds
key: secret-key
EOF
# Criar ExternalSecret
cat <<EOF | kubectl apply -f -
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 30m
secretStoreRef:
name: aws-store
kind: SecretStore
target:
name: db-credentials
data:
- secretKey: password
remoteRef:
key: /prod/database/password
EOF
6.3. Exemplo 3: Vault Injector com sidecar
# Anotação no Deployment para ativar o injector
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp-role"
vault.hashicorp.com/agent-inject-secret-db-creds: "secret/data/myapp/db"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "secret/data/myapp/db" -}}
export DB_PASSWORD="{{ .Data.data.password }}"
{{- end }}
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
spec:
serviceAccountName: myapp-sa
containers:
- name: myapp
image: node:18
command: ["sh", "-c", "source /vault/secrets/db-creds && node app.js"]
7. Boas Práticas e Segurança Avançada
7.1. Gerenciamento de chaves
- Vault: use KMS (AWS KMS, Azure Key Vault) para auto-unseal, evite unseal keys manuais
- Sealed Secrets: faça backup da chave mestra (
kubeseal --fetch-cert > master.crt) e armazene em cofre seguro - External Secrets: as credenciais do SecretStore devem ser rotacionadas periodicamente
7.2. Network Policies
Isole o tráfego do operador de secrets para o provedor externo usando NetworkPolicies:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: external-secrets-egress
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: external-secrets
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8 # Intervalo IP do provedor
ports:
- protocol: TCP
port: 443
7.3. Monitoramento e alertas
Configure métricas de falha de decriptação, tempo de sincronização e acesso a segredos. Prometheus + Grafana com dashboards específicos para cada operador.
8. Tendências e Futuro do Secrets Management
8.1. Convergência com Service Mesh
SPIFFE/SPIRE e Istio estão integrando identidade de workload para autorização de acesso a segredos, eliminando a necessidade de tokens estáticos.
8.2. Secrets nativos com KMS Encryption Provider
O Kubernetes 1.24+ permite criptografar Secrets em repouso no etcd usando KMS externo (AWS KMS, Azure Key Vault, GCP Cloud KMS), uma alternativa mais simples que operadores externos.
8.3. Serverless e edge
Ambientes efêmeros como Knative e K3s exigem soluções leves. External Secrets Operator com polling rápido e Sealed Secrets (sem dependência de rede) são as escolhas naturais.
Referências
- HashiCorp Vault Documentation - Kubernetes Integration — Documentação oficial sobre Vault Agent Injector, CSI Provider e autenticação Kubernetes
- Bitnami Sealed Secrets GitHub Repository — Código fonte, documentação e exemplos de uso do Sealed Secrets controller
- External Secrets Operator Official Documentation — Guia completo de instalação, provedores suportados e CRDs
- Kubernetes Secrets - Official Documentation — Documentação oficial sobre Secrets nativos e boas práticas de segurança
- Managing Secrets in Kubernetes with Vault - Tutorial by DigitalOcean — Tutorial prático de integração Vault + Kubernetes com exemplos passo a passo
- Sealed Secrets vs External Secrets - Comparison by CNCF — Artigo técnico comparando as duas abordagens com casos de uso reais
- AWS Secrets Manager Integration with External Secrets Operator — Guia oficial da AWS para integração com External Secrets Operator