Pular para o conteúdo

Gestão de segredos

Avançado20 min de leituradevsecops

Segredo bem gerido tem três propriedades: vida curta, escopo mínimo e rotação que não exige janela de manutenção. Quase todo incidente com credencial vem de violar uma dessas três — a chave de dez anos, com permissão de administrador, que ninguém troca porque não se sabe quem a usa.

Antes da ferramenta, conheça os caminhos reais:

  • Commitado no repositório — inclusive em histórico já reescrito e em fork.
  • Variável de ambiente impressa em log de erro ou de build.
  • terraform.tfstate e plan guardados sem criptografia (o state guarda valor em claro).
  • Secret do Kubernetes, que é base64, não criptografia, legível por quem tem get no namespace.
  • Imagem de container com arquivo .env em uma camada intermediária.
  • Print de tela em chamado, e mensagem de chat com “a chave é essa aqui”.

O cofre centraliza guarda, controle de acesso e auditoria. O nativo da nuvem (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) é o caminho mais curto se você já vive naquela nuvem: integra com a identidade existente e não é mais um sistema para operar. O Vault ganha quando há várias nuvens, ou quando você quer segredos dinâmicos.

Em vez de guardar a senha do banco, a aplicação pede uma credencial criada na hora, com validade de uma hora e permissão só do que precisa. Se vazar, expira sozinha; a rotação deixa de ser projeto.

Janela do terminal
# Vault: o banco de dados passa a emitir credencial temporária
vault write database/roles/loja-leitura \
db_name=postgres-prod \
creation_statements="CREATE ROLE \"{{name}}\" LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl=1h max_ttl=8h
vault read database/creds/loja-leitura # devolve usuário e senha novos

A aplicação precisa saber renovar a credencial e reconectar quando ela expirar. Se o código assume credencial eterna, o segredo dinâmico troca um risco por uma queda às 4h.

Para o CI, o equivalente é OIDC: o pipeline troca um token de identidade por credencial temporária da nuvem, e nenhuma chave fica armazenada no repositório.

Dentro do Kubernetes, o operador busca o valor no cofre e mantém o Secret sincronizado — o manifest versionado passa a conter apenas a referência, nunca o valor.

apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata: { name: loja-db, namespace: loja }
spec:
refreshInterval: 1h
secretStoreRef: { name: vault-prod, kind: ClusterSecretStore }
target: { name: loja-db } # o Secret criado no cluster
data:
- secretKey: senha
remoteRef: { key: prod/loja/postgres, property: senha }

Complete com o básico do cluster: criptografia em repouso no etcd (ou provedor KMS externo), RBAC negando get secrets por padrão, e nenhum segredo montado em Pod que não precise dele. Quem tem acesso ao Secret tem acesso ao banco — trate a permissão como se fosse a senha.

Duas camadas, porque uma sempre falha:

Janela do terminal
# 1. antes do commit, na máquina de quem escreve
gitleaks protect --staged --redact
# 2. no CI, no histórico completo, para o que passou
gitleaks detect --redact --log-opts="--all"

Ative também a varredura do provedor (GitHub secret scanning e push protection). Ela pega formato conhecido de token e, em muitos casos, revoga junto com o fornecedor.

A ordem importa, e a primeira etapa não é apagar o commit:

  1. Revogue e rotacione primeiro. Enquanto a credencial for válida, o resto é secundário. Considere-a comprometida mesmo que o repositório seja privado.
  2. Avalie o uso. Trilha de auditoria do provedor: houve acesso de IP ou horário fora do padrão desde o vazamento?
  3. Limpe a exposição. Reescrever o histórico (git filter-repo) ajuda, mas o segredo já pode estar em fork, cache e CDN do provedor. Reescrita não substitui a rotação.
  4. Comunique. Segurança, dono do dado e, se houver dado pessoal envolvido, o encarregado pela LGPD.
  5. Registre em postmortem. Por que era possível commitar aquilo? Onde estava o guarda-corpo? A ação corretiva é sempre estrutural — hook, varredura, template.

Faça uma vez o exercício de responder: se a sua chave mais sensível vazar hoje às 15h, quanto tempo até ela ser inválida? Se a resposta passar de uma hora, o trabalho começa por aí.

Próximo passo: para transformar essas regras em verificação automática, siga para Política como código.