O HashiCorp Vault resolve um dos problemas mais persistentes da infraestrutura moderna: onde armazenar e distribuir segredos com segurança? Credenciais hardcoded em arquivos de configuração, variáveis de ambiente commitadas no git e planilhas de senhas compartilhadas são responsáveis por uma parcela desproporcional de brechas de segurança. O HashiCorp Vault fornece uma API unificada para gerenciamento de segredos, geração de credenciais dinâmicas, criptografia como serviço e controle de acesso granular — tudo com uma trilha de auditoria completa. Neste guia você aprenderá como o Vault funciona, como implantá-lo e como integrá-lo ao Kubernetes e ao Terraform em um fluxo de trabalho real de produção.
Pré-requisitos
- Host Linux ou macOS (ou um cluster Kubernetes para o caminho cloud-native)
- Familiaridade básica com linha de comando e configuração YAML
- Docker (opcional, para um servidor de desenvolvimento rápido)
- Um cluster Kubernetes com acesso via
kubectl(para a seção de integração com Kubernetes) - Terraform 1.x instalado (para a seção do provider Terraform)
- Conhecimento de certificados TLS é útil, mas não obrigatório
Como o HashiCorp Vault Funciona
Em sua essência, o Vault é um processo que expõe uma API HTTP. Tudo — leitura de segredos, autenticação, gerenciamento de políticas — passa por essa API. O Vault armazena seus dados em um storage backend (o Integrated Storage baseado em Raft é o padrão recomendado) e criptografa tudo em repouso usando uma chave mestra que nunca sai da memória.
Quando o Vault inicia, ele está selado: mantém os dados criptografados, mas não consegue descriptografá-los porque a chave mestra é dividida em vários shares de unseal usando o Compartilhamento de Segredo de Shamir. O Vault só se torna operacional após o quórum mínimo de shares ser fornecido. Esse design garante que, mesmo que alguém roube o storage backend, não consiga ler nenhum segredo sem as chaves de unseal.
Conceitos fundamentais
- Secrets engines — plugins que geram ou armazenam segredos. O engine KV armazena pares chave/valor estáticos. O engine Database gera credenciais dinâmicas. O engine PKI emite certificados X.509.
- Métodos de autenticação — como os clientes provam identidade ao Vault. As opções incluem AppRole (para máquinas), service accounts do Kubernetes, AWS IAM, LDAP, GitHub e OIDC.
- Políticas — arquivos HCL que concedem acesso de leitura, escrita ou administração a caminhos específicos no Vault.
- Leases e TTLs — todo segredo tem um lease; quando o lease expira, o Vault o revoga. As aplicações devem renovar ou solicitar novamente as credenciais antes do vencimento.
- Dispositivos de auditoria — o Vault pode gravar cada requisição e resposta em um arquivo de log, syslog ou socket. A auditoria é à prova de adulteração e verificada criptograficamente.
Instalando e Inicializando o Vault
Para uma implantação de nível de produção, a HashiCorp recomenda executar o Vault em modo de Alta Disponibilidade (HA) com Integrated Storage em três ou cinco nós. Para fins de aprendizado, um único servidor de desenvolvimento é suficiente.
Servidor de desenvolvimento rápido (não para produção):
vault server -dev
Isso inicia um Vault em memória, faz o unseal automaticamente e exibe um token root. Os dados são perdidos quando o processo termina.
Nó único de produção com Integrated Storage:
Crie /etc/vault.d/vault.hcl:
ui = true
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-node-1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/vault.crt"
tls_key_file = "/opt/vault/tls/vault.key"
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
Inicie o serviço e depois inicialize-o:
vault operator init -key-shares=5 -key-threshold=3
Isso gera cinco chaves de unseal e um token root. Guarde-os imediatamente em locais seguros separados — perder shares suficientes significa perder o acesso a todos os seus dados permanentemente. Faça o unseal com três das cinco chaves:
vault operator unseal <key-1>
vault operator unseal <key-2>
vault operator unseal <key-3>
Segredos Dinâmicos: A Principal Vantagem
Credenciais estáticas (uma senha de banco de dados que nunca muda) são um risco. Se vazarem, a janela de exposição é indefinida. Os segredos dinâmicos fecham essa janela.
Habilite o database secrets engine e configure-o para PostgreSQL:
vault secrets enable database
vault write database/config/myapp-db \
plugin_name=postgresql-database-plugin \
allowed_roles="myapp-role" \
connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/myapp" \
username="vault" \
password="vault-superuser-password"
vault write database/roles/myapp-role \
db_name=myapp-db \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
Agora qualquer aplicação ou job de CI com a política correta do Vault pode executar:
vault read database/creds/myapp-role
O Vault se conecta ao PostgreSQL, cria um usuário com nome único e retorna credenciais que expiram em uma hora. Quando o lease expira (ou a aplicação chama vault lease revoke), o Vault remove o usuário do banco de dados. A aplicação nunca mantém uma senha de longa duração.
PKI Secrets Engine para Certificados Internos
Gerenciar certificados TLS manualmente é propenso a erros e raramente auditado. O PKI secrets engine do Vault atua como uma Autoridade Certificadora interna, emitindo certificados de curta duração sob demanda.
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
# Gerar CA raiz (armazene o cert externamente, offline se possível)
vault write -field=certificate pki/root/generate/internal \
common_name="example.com" \
ttl=87600h > CA_cert.crt
# Configurar URLs de CRL e emissão
vault write pki/config/urls \
issuing_certificates="https://vault.example.com:8200/v1/pki/ca" \
crl_distribution_points="https://vault.example.com:8200/v1/pki/crl"
# Habilitar CA intermediária (boa prática para produção)
vault secrets enable -path=pki_int pki
vault write -format=json pki_int/intermediate/generate/internal \
common_name="example.com Intermediate Authority" | jq -r '.data.csr' > pki_int.csr
vault write -format=json pki/root/sign-intermediate csr=@pki_int.csr \
format=pem_bundle ttl="43800h" | jq -r '.data.certificate' > intermediate.cert.pem
vault write pki_int/intermediate/set-signed certificate=@intermediate.cert.pem
# Criar uma role para emitir certificados de servidor
vault write pki_int/roles/example-dot-com \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl="72h"
Qualquer serviço que precise de um certificado TLS solicita um com:
vault write pki_int/issue/example-dot-com common_name="api.example.com" ttl="24h"
Certificados válidos por 24 horas eliminam o risco de rotações esquecidas.
Integração com Kubernetes via Vault Agent Injector
Os Kubernetes Secrets são codificados em base64 e armazenados no etcd. Sem controles adicionais, qualquer usuário com acesso a kubectl get secret pode lê-los. O Agent Injector do Vault mantém os segredos completamente fora do Kubernetes.
Instale com Helm:
helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault \
--set "injector.enabled=true" \
--set "server.dev.enabled=false"
Habilite e configure a autenticação Kubernetes no Vault:
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Crie uma política e uma role:
vault policy write myapp - <<EOF
path "secret/data/myapp/*" {
capabilities = ["read"]
}
EOF
vault write auth/kubernetes/role/myapp \
bound_service_account_names=myapp \
bound_service_account_namespaces=production \
policies=myapp \
ttl=1h
Anote seu pod para injetar segredos em tempo de execução:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp"
vault.hashicorp.com/agent-inject-secret-config.env: "secret/data/myapp/config"
vault.hashicorp.com/agent-inject-template-config.env: |
{{- with secret "secret/data/myapp/config" -}}
export DB_PASSWORD="{{ .Data.data.db_password }}"
{{- end }}
O sidecar Vault Agent autentica, busca o segredo, escreve em um volume em memória compartilhado e o renova antes do vencimento. A aplicação lê um arquivo — nunca faz uma chamada à API do Vault.
Comparação: Vault vs. Alternativas de Gerenciamento de Segredos
| Funcionalidade | HashiCorp Vault | AWS Secrets Manager | Azure Key Vault | Kubernetes Secrets |
|---|---|---|---|---|
| Segredos dinâmicos | Sim (banco, nuvem, PKI) | Limitado (somente RDS) | Não | Não |
| Multi-cloud | Sim | Somente AWS | Somente Azure | Sim (com CSI) |
| PKI / CA | CA completa com CRL | Não | Sim (limitado) | Não |
| Auditoria | Nativa, à prova de adulteração | CloudTrail | Azure Monitor | Requer add-on |
| Self-hosted | Sim | Não | Não | Sim |
| Custo | Gratuito (Community) | Por segredo + chamada API | Por operação | Gratuito |
| Nativo Kubernetes | Agent Injector / VSO | Driver CSI | Driver CSI | Nativo |
| Curva de aprendizado | Alta | Baixa | Baixa | Muito baixa |
O Vault é a escolha certa quando você precisa de gerenciamento de segredos auditável e independente de fornecedor com geração de credenciais dinâmicas em múltiplas plataformas. O AWS Secrets Manager vence quando você é 100% AWS-native e a simplicidade é a prioridade.
Cenário Real: Protegendo uma Aplicação Multi-Camada
Você tem um cluster Kubernetes em produção executando uma API Node.js, um banco de dados PostgreSQL e um cache Redis. Sua configuração atual armazena a senha do banco como um Kubernetes Secret e a senha do Redis em um ConfigMap. Uma auditoria interna recente sinalizou ambos como riscos de conformidade.
Aqui está o caminho de migração:
- Implante o Vault em modo HA (3 nós) ao lado do cluster usando Helm. Use Integrated Storage com quórum Raft.
- Habilite segredos dinâmicos para PostgreSQL. Remova a variável de ambiente estática
PGPASSWORD. O Vault Agent Injector escreve um novo arquivo de credencial a cada 55 minutos (antes do TTL de 1 hora expirar). - Armazene a senha do Redis no Vault KV v2 em
secret/data/production/redis. O Agent Injector a injeta como/vault/secrets/redis.env, carregada pelo script de entrypoint da aplicação. - Habilite PKI para o TLS interno entre a API e o banco de dados. Os certificados rotacionam a cada 24 horas automaticamente.
- Configure auditoria para gravar em um destino syslog encaminhado ao seu SIEM. Todo acesso a segredos é rastreado com identidade do cliente, IP de origem e timestamp.
- Integre com Terraform usando o provider Vault para gerenciar políticas e roles como código, versionado no seu repositório de infraestrutura.
Resultado: nenhum segredo no etcd do Kubernetes, nenhuma credencial estática, trilha de auditoria completa e rotação automática — sem alterar uma linha do código da aplicação.
Armadilhas e Casos Especiais
Resselamento após reinicialização. O Vault se ressela a cada reinicialização do processo. Você precisa de um mecanismo de unseal automatizado em produção. As opções são o Auto Unseal da HashiCorp (usando AWS KMS, GCP Cloud KMS ou Azure Key Vault como fonte da chave), ou a integração com um Vault HSM. Planeje isso antes de implantar em produção.
Explosão de leases. Se você gerar segredos dinâmicos para milhares de jobs de CI de curta duração e nunca revogá-los explicitamente, o armazenamento de leases do Vault cresce sem limite e eventualmente degrada o desempenho. Sempre chame vault lease revoke ao final de um job, ou use o Vault Agent, que gerencia renovação e revogação automaticamente.
Token root deve ser revogado. O token root gerado durante o vault operator init tem acesso irrestrito. Após a configuração inicial, gere um token root com tempo limitado para uso emergencial e revogue o original: vault token revoke <root-token>.
Desempenho do storage backend. O Integrated Storage (Raft) funciona bem para a maioria das cargas de trabalho, mas é sensível à latência de I/O do disco. Em VMs na nuvem, use volumes com SSD. Evite NFS ou armazenamento em rede para o diretório de dados do Raft.
Confusão de namespaces. Os namespaces do Vault Enterprise são unidades de isolamento lógico (como instâncias Vault separadas). O Vault Community Edition não tem namespaces. Se você testar com Enterprise e implantar Community, os caminhos que funcionavam antes não existirão.
Desvio de relógio. Vários métodos de autenticação (AWS IAM, Kubernetes, JWT) validam tokens assinados com timestamp. Se os relógios do servidor divergirem mais de alguns segundos, a autenticação falha silenciosamente. Garanta que o NTP esteja configurado em todos os nós do Vault.
Solução de Problemas
“Error initializing: Post https://127.0.0.1:8200/v1/sys/init: x509: certificate signed by unknown authority”
Defina VAULT_SKIP_VERIFY=true apenas para testes, ou adicione seu certificado de CA ao repositório de confiança do sistema e defina VAULT_CACERT=/path/to/ca.crt.
“Error making API request: Code: 503. Errors: Vault is sealed.”
O Vault foi reiniciado e aguarda as chaves de unseal. Execute vault operator unseal com o número necessário de shares, ou verifique sua configuração de Auto Unseal.
O Vault Agent falha ao autenticar no Kubernetes com “permission denied”
Verifique se o nome do ServiceAccount e o namespace do pod correspondem exatamente a bound_service_account_names e bound_service_account_namespaces na role Kubernetes do Vault. Verifique também se a política do Vault concede acesso aos caminhos solicitados.
“context deadline exceeded” ao ler do banco de dados
O plugin de banco de dados não consegue alcançar o host do banco. Verifique a connection_url em database/config/<name>, confirme a conectividade de rede e as regras de firewall entre o Vault e o banco, e certifique-se de que o superusuário do Vault tem privilégios CREATEROLE.
Segredos não atualizando em um pod em execução após renovação pelo Vault Agent
Por padrão, o Vault Agent renderiza templates em arquivos. A aplicação deve monitorar o arquivo por alterações ou reiniciar para receber as novas credenciais. Use o bloco command na estância de template do Vault Agent para acionar um kill -HUP ou sinal similar.
Resumo
- O HashiCorp Vault é o padrão da indústria para gerenciamento de segredos auditável e independente de fornecedor em ambientes de nuvem e on-premises.
- O engine KV v2 gerencia segredos estáticos; os engines Database e PKI geram credenciais e certificados dinâmicos de curta duração que se auto-revogam.
- O Vault Agent desacopla sua aplicação da API do Vault — ele cuida de autenticação, busca de segredos, renderização de templates, renovação e revogação.
- A integração com Kubernetes via Agent Injector ou Vault Secrets Operator elimina os Kubernetes Secrets estáticos e a exposição no etcd.
- Toda operação no Vault é capturada em logs de auditoria, fornecendo um registro completo e à prova de adulteração para conformidade.
- Planeje o Auto Unseal desde o primeiro dia para evitar interrupções operacionais quando os nós do Vault reiniciarem.
- Segredos dinâmicos reduzem drasticamente o raio de explosão de um vazamento de credencial — uma credencial de banco de dados válida por uma hora é muito menos perigosa que uma senha válida há três anos.