Blog

Gerenciamento de Secrets no Kubernetes: Protegendo Dados Sensíveis

Gerenciamento de Secrets no Kubernetes bem feito: criptografia em repouso no etcd, RBAC, secrets externos, rotação, GitOps e scanning shift-left.

Bruno Baldo·14 de set. de 2026·11 min de leitura·Revisado por Rainforest Technologies
O gerenciamento de Secrets no Kubernetes é um daqueles temas que parece resolvido no primeiro dia e, silenciosamente, se torna um passivo por volta do centésimo. Você cria um Secret, o referencia a partir de um Deployment e a aplicação inicia. Funciona, então parece seguro. A verdade incômoda é que um Secret padrão do Kubernetes, por si só, protege quase nada, e é justamente na lacuna entre "funciona" e "está protegido" que os incidentes reais acontecem. Este mergulho profundo faz parte do nosso guia mais amplo de segurança do Kubernetes. Aqui nos concentramos em uma única coisa e a fazemos com rigor: como armazenar, distribuir e proteger dados sensíveis, como senhas de banco de dados, tokens de API, chaves TLS e credenciais de nuvem, ao longo de toda a vida de um cluster. O que são os Secrets do Kubernetes e a grande ressalva Um Secret do Kubernetes é um objeto de API projetado para armazenar pequenas quantidades de dados sensíveis, de modo que eles não precisem ser embutidos em uma spec de Pod ou em uma imagem de contêiner. Em comparação com colocar uma senha diretamente em um manifesto de Deployment, isso é genuinamente um avanço: o valor vive em seu próprio objeto, pode ser montado ou injetado sob demanda e pode ser governado por controles de acesso. Aqui está a ressalva que surpreende muitas equipes: por padrão, os dados de um Secret são apenas codificados em base64, não criptografados. Base64 é uma codificação, não uma cifra. Não possui chave e não oferece confidencialidade alguma. Qualquer pessoa que consiga ler o objeto Secret pode decodificá-lo com um único comando: kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d Pior ainda, os valores dos Secrets são armazenados no etcd, o datastore de apoio do cluster. Se o etcd não estiver criptografado, um arquivo de backup, um snapshot, um disco roubado ou o acesso direto ao etcd expõem todos os secrets do cluster em um formato trivial de ler. Portanto, o modelo mental a adotar é simples: um Secret é um contêiner conveniente para dados sensíveis, não uma garantia de que os dados estão seguros. Tudo o que vem a seguir trata de fechar essa lacuna. Criptografia em repouso: EncryptionConfiguration e um provedor KMS O primeiro controle a adicionar é a criptografia em repouso no etcd. O Kubernetes suporta criptografar recursos Secret antes que eles sejam gravados no etcd, o que é configurado por meio de um arquivo EncryptionConfiguration que o API server carrega via --encryption-provider-config. Você pode criptografar com uma chave gerenciada localmente, mas a opção mais robusta e operacionalmente mais sólida é um provedor KMS. Com o KMS, as próprias chaves de criptografia de dados são encapsuladas por uma chave mantida em um serviço externo de gerenciamento de chaves, de modo que a chave bruta nunca fica em um arquivo de configuração no control plane, e você pode rotacioná-la e auditá-la de forma independente. Uma configuração apoiada por KMS se parece aproximadamente com isto: apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources:   - resources:       - secrets     providers:       - kms:           apiVersion: v2           name: my-kms-provider           endpoint: unix:///var/run/kmsplugin/socket.sock       - identity: {} Duas observações práticas. Primeira, a ordem importa: o provedor listado primeiro é usado para criptografar novas gravações, enquanto todos os provedores listados podem descriptografar, que é exatamente como você migra de identity (texto puro) para criptografia e, mais tarde, rotaciona chaves. Segunda, habilitar a criptografia afeta apenas gravações futuras. Para criptografar secrets que já existem, force uma regravação após a mudança: kubectl get secrets --all-namespaces -o json | kubectl replace -f - A criptografia em repouso é o controle que transforma "qualquer um com um snapshot do etcd é dono das suas credenciais" em "o atacante também precisa da chave do KMS". Isso representa um aumento significativo de custo para o atacante. Quem pode ler os secrets: RBAC e o perigo de get/list amplos A criptografia protege os dados em repouso, mas, dentro de um cluster em execução, o caminho de exposição mais comum é a autorização. Se um usuário, uma service account ou uma carga de trabalho consegue chamar a API e ler um Secret, a criptografia em repouso não os impede, porque o API server descriptografa na saída. É por isso que o RBAC sobre secrets merece um escrutínio especial. Uma role que concede get, list ou watch sobre o recurso secrets é, na prática, uma role capaz de ler credenciais. Concedida de forma ampla, no escopo do cluster ou com um curinga, ela se torna um caminho para todos os secrets do cluster. Trate esses verbos como de alto privilégio e limite seu escopo com rigor: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata:   namespace: payments   name: read-payments-db-secret rules:   - apiGroups: [""]     resources: ["secrets"]     verbs: ["get"]     resourceNames: ["payments-db"] Observe o campo resourceNames, que restringe a concessão a um único Secret nomeado, em vez de todos os secrets do namespace. Prefira Roles com escopo de namespace em vez de ClusterRoles para acesso a secrets, evite list e watch a menos que uma carga de trabalho realmente precise enumerar secrets, e lembre-se de que a service account de um Pod herda tudo o que aquela conta pode fazer. Para um tratamento completo do design de roles com privilégio mínimo, veja nosso guia sobre RBAC no Kubernetes. Evitando vazamentos: imagens, variáveis de ambiente e logs Algumas das piores exposições de secrets nunca chegam a tocar o etcd. Elas vazam porque o secret foi copiado para algum lugar de forma descuidada. Não embuta secrets em imagens de contêiner. Uma credencial adicionada durante um build permanece nas camadas da imagem e viaja para todo registry e nó que a baixa. As camadas de imagem não são um lugar seguro para nada sensível. Tenha cautela com variáveis de ambiente. Injetar um Secret como variável de ambiente é conveniente, mas as variáveis de ambiente têm o hábito de acabar em crash dumps, rastreadores de erros, na saída de kubectl describe para a spec do Pod e em processos filhos. Sempre que possível, prefira montar os secrets como arquivos por meio de um volume. Arquivos montados são lidos sob demanda, podem ser atualizados no local e têm menos probabilidade de serem capturados incidentalmente. Cuidado com os logs. Logs de aplicação, traces de depuração e banners de inicialização que ecoam a configuração são um canal clássico de vazamento. Um secret que está seguramente criptografado no etcd não vale nada como proteção se a aplicação o imprime no stdout durante o boot. Montar um secret como arquivo é simples: volumes:   - name: db-creds     secret:       secretName: payments-db containers:   - name: api     volumeMounts:       - name: db-creds         mountPath: /etc/secrets         readOnly: true Stores de secrets externos e o Secrets Store CSI Driver Para muitas equipes, a resposta certa no longo prazo é parar de tratar o cluster como a fonte da verdade para os secrets e, em vez disso, mantê-los em um gerenciador de secrets externo dedicado, apoiado por um KMS, com suas próprias políticas de acesso, versionamento e trilha de auditoria. O cluster então puxa os secrets em tempo de execução, em vez de armazená-los permanentemente. O padrão comum e neutro em relação a fornecedores para isso é o Secrets Store CSI Driver. Ele monta secrets de um store externo diretamente em um Pod como um volume, de modo que o valor sensível é entregue à carga de trabalho que precisa dele sem necessariamente persistir como um Secret nativo do Kubernetes. Um objeto SecretProviderClass descreve quais secrets externos buscar, e o Pod o referencia como um volume CSI: apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata:   name: payments-db spec:   provider:   parameters:     objects: |       - objectName: "payments-db-password"         objectType: "secret" volumes:   - name: secrets-store     csi:       driver: secrets-store.csi.x-k8s.io       readOnly: true       volumeAttributes:         secretProviderClass: payments-db Os benefícios são uma política centralizada, um único lugar para rotacionar e revogar, e uma trilha de auditoria que vive fora do cluster. Outro padrão relacionado usa um operador que sincroniza de um store externo para Secrets nativos, o que é mais fácil de adotar, mas reintroduz a cópia dentro do cluster, então combine-o com criptografia em repouso e RBAC rigoroso. Rotação e credenciais de curta duração Secrets estáticos que nunca mudam são um risco permanente: quanto mais tempo uma credencial vive, para mais lugares ela vaza e maior é o raio de impacto quando isso acontece. Um bom gerenciamento de secrets pressupõe a rotação desde o início. Dois hábitos complementares ajudam aqui. Primeiro, rotacione regularmente e faça da rotação uma operação rotineira e automatizada, em vez de uma correria manual após um incidente. Os stores de secrets externos facilitam muito isso, porque a rotação acontece em um único lugar e as cargas de trabalho pegam o novo valor na próxima montagem ou atualização. Segundo, prefira credenciais de curta duração, emitidas dinamicamente sempre que a plataforma permitir, como credenciais de banco de dados que são geradas sob demanda e expiram em horas, ou acesso à nuvem concedido por meio de federação de identidade de carga de trabalho em vez de chaves estáticas de longa duração. Uma credencial que expira sozinha é uma credencial que você não precisa se lembrar de revogar. Secrets selados e criptografados no Git para GitOps O GitOps é um modelo operacional maravilhoso, e ele colide frontalmente com os secrets: você quer todo o seu estado desejado sob controle de versão, mas nunca deve commitar secrets em texto puro em um repositório. O histórico do Git é durável e amplamente replicado, então um secret commitado uma vez está, na prática, vazado para sempre, mesmo depois de um commit de "correção" posterior. A solução é commitar apenas material secreto criptografado. Duas abordagens consolidadas e neutras em relação a fornecedores: Sealed secrets, em que um controlador no cluster mantém uma chave privada e você commita um objeto criptografado com chave pública que apenas esse controlador consegue descriptografar. O objeto criptografado é seguro para armazenar no Git; o texto puro nunca sai da sua máquina ou do cluster. Criptografia em nível de arquivo dos manifestos de secrets usando uma ferramenta de criptografia com chaves mantidas em um KMS, de modo que os valores no YAML commitado sejam texto cifrado e só sejam descriptografados no pipeline de entrega ou por um operador dentro do cluster. De uma forma ou de outra, a regra é a mesma: o repositório contém texto cifrado, e a chave de descriptografia vive em algum lugar que o repositório não consegue alcançar. Nunca deixe um secret em texto puro cair em um commit, em um diff de pull request ou em um log de CI. Auditando o acesso aos secrets Você não consegue proteger o que não consegue ver. O audit log do Kubernetes registra as requisições ao API server, incluindo leituras de objetos Secret, e é um dos sinais de segurança mais valiosos e mais subutilizados de um cluster. Configure uma política de auditoria que capture o acesso ao recurso secrets, envie esses logs para um sistema que você de fato revisa e alerte sobre os padrões anômalos: uma service account inesperada lendo secrets, um list repentino em todos os namespaces ou acesso a partir de uma carga de trabalho que não tem nada a ver com credenciais. A auditoria serve a dois propósitos. No dia a dia, é detecção. Após um incidente, é o registro que diz exatamente quais secrets foram tocados e, portanto, quais precisam ser rotacionados. Ambos são muito melhores do que adivinhar. Shift left: pegue problemas de secrets antes que eles entrem em produção Tudo o que foi dito acima é um controle de tempo de execução. O lugar mais barato para corrigir um problema de secrets, no entanto, é antes que ele chegue a um cluster, que é o coração do desenvolvimento seguro de software. Duas práticas se pagam rapidamente: Detecte secrets embutidos no código no CI. Escaneie o código-fonte, os manifestos e o histórico de commits em busca de tokens, chaves e senhas para que uma credencial seja pega no pull request em vez de depois de ter sido implantada e cacheada em uma dúzia de lugares. Escaneie manifestos e IaC. O scanning de infraestrutura como código automatizado sinaliza as configurações incorretas que discutimos: etcd não criptografado, RBAC excessivamente amplo sobre secrets, secrets injetados como variáveis de ambiente e Deployments que referenciam dados sensíveis de forma insegura, tudo antes que sejam aplicados. O shift-left transforma o gerenciamento de secrets de um exercício de combate a incêndios em um guardrail que roda a cada mudança. Como a Rainforest ajuda A Rainforest foi construída para pegar exatamente esses problemas cedo. Seu secret scanning vasculha seu código e sua configuração em busca de credenciais embutidas no código e secrets commitados por acidente, para que um token vazado seja sinalizado no pull request em vez de descoberto em uma análise de incidente. Seu IaC scanning inspeciona seus manifestos do Kubernetes e definições de infraestrutura em busca das configurações incorretas que comprometem o gerenciamento de secrets: falta de criptografia em repouso, RBAC excessivamente permissivo e manuseio inseguro de secrets em specs de Pod. Juntos, eles oferecem uma rede de segurança shift-left que complementa os controles de tempo de execução deste guia, tudo a partir de uma única plataforma de application security testing. Se você quiser ver como isso funciona nos seus próprios manifestos e repositórios, agende uma demonstração e mostraremos tudo junto com você.

Perguntas frequentes

Os secrets do Kubernetes são criptografados por padrão?

Não. Por padrão, os dados de um Secret do Kubernetes são apenas codificados em base64, que é uma codificação sem chave e sem confidencialidade, e ficam armazenados no etcd. Qualquer pessoa que consiga ler o objeto Secret ou acessar o datastore etcd, incluindo um backup ou snapshot, pode recuperar o texto puro. Para realmente criptografar os secrets, você precisa habilitar a criptografia em repouso e controlar o acesso com RBAC.

Como eu criptografo os secrets do Kubernetes em repouso?

Configure um EncryptionConfiguration e aponte o API server para ele com --encryption-provider-config. A opção mais robusta é um provedor KMS, que encapsula as chaves de criptografia de dados com uma chave mantida em um serviço externo de gerenciamento de chaves, de modo que a chave bruta nunca fique armazenada no control plane. Lembre-se de que a criptografia se aplica apenas a novas gravações, então regrave os secrets existentes depois para criptografá-los.

Devo armazenar secrets no Git?

Nunca armazene secrets em texto puro no Git. O histórico do Git é durável e amplamente replicado, então um secret commitado uma vez está, na prática, vazado permanentemente. Para GitOps, commite apenas material secreto criptografado, usando sealed secrets ou criptografia em nível de arquivo apoiada por um KMS, e mantenha a chave de descriptografia em algum lugar que o repositório não consiga alcançar.

Como eu limito quem pode ler os secrets?

Use um RBAC rigoroso. Trate get, list e watch sobre o recurso secrets como acesso de alto privilégio a credenciais. Prefira Roles com escopo de namespace em vez de ClusterRoles, use resourceNames para restringir uma concessão a secrets nomeados específicos, evite list e watch a menos que sejam realmente necessários, e lembre-se de que um Pod herda as permissões da sua service account.

O que é o Secrets Store CSI Driver?

É um padrão do Kubernetes neutro em relação a fornecedores para montar secrets de um gerenciador de secrets externo diretamente em um Pod como um volume, de modo que o valor sensível seja entregue em tempo de execução sem necessariamente persistir como um Secret nativo do Kubernetes. Um SecretProviderClass descreve quais secrets externos buscar, dando a você política centralizada, rotação e auditoria fora do cluster.

Bruno Baldo

Escrito por

Bruno Baldo

CMO

Um pouco de marketing e um pouco de curiosidade e temos a receita pra criar um apaixonado por cyber!

Continue lendo