HashiCorp Vault: gerenciando segredos em produção

1. Por que o Vault é Essencial para a Segurança em Produção

O gerenciamento de segredos é um dos maiores desafios de segurança em ambientes de produção. Segredos como senhas de banco de dados, tokens de API e certificados TLS frequentemente acabam "hardcoded" no código-fonte, em arquivos .env ou em variáveis de ambiente estáticas. Essa prática cria riscos enormes: um repositório vazado expõe credenciais, um dump de memória revela tokens, e a rotação manual de segredos se torna inviável em escala.

O HashiCorp Vault resolve esse problema oferecendo um sistema centralizado para armazenar, acessar e rotacionar segredos de forma segura. Diferente de variáveis de ambiente estáticas, o Vault permite:

  • Segredos dinâmicos: gerados sob demanda com tempo de vida limitado (TTL)
  • Auditoria completa: cada acesso é registrado
  • Políticas granulares: controle preciso sobre quem pode acessar o quê
  • Rotação automática: segredos expiram e são renovados sem intervenção manual

Casos de uso típicos incluem senhas de banco de dados PostgreSQL, tokens de API do AWS, certificados TLS para microsserviços e chaves de criptografia.

2. Arquitetura Básica do Vault

A arquitetura do Vault é composta por três componentes principais:

  • Servidor Vault: expõe uma API HTTP/HTTPS e gerencia o ciclo de vida dos segredos
  • Storage Backend: armazena os dados criptografados (consul, raft, file system)
  • Selo (Seal): mecanismo que criptografa a chave mestra, protegendo dados em repouso

Em modo desenvolvimento, o Vault roda sem selo e com configuração mínima. Em produção, é essencial usar modo de alta disponibilidade (HA) com selo automático (Auto Unseal) via AWS KMS, GCP Cloud KMS ou Azure Key Vault.

Os caminhos (paths) organizam os segredos de forma hierárquica. Por exemplo:

secret/data/myapp/database
secret/data/myapp/api-keys

Políticas ACL (Access Control Lists) definem permissões para cada caminho:

path "secret/data/myapp/*" {
  capabilities = ["read", "list"]
}

3. Autenticação e Autorização de Aplicações

O Vault suporta múltiplos métodos de autenticação. Para aplicações em produção, o AppRole é o mais comum:

  1. A aplicação obtém um RoleID e um SecretID
  2. Autentica-se na API do Vault para receber um token temporário
  3. Usa o token para ler segredos

Exemplo de autenticação via API:

# Login com AppRole
curl --request POST \
  --data '{"role_id":"6b2b6f5c-...","secret_id":"8e8b8f5d-..."}' \
  http://vault:8200/v1/auth/approle/login

# Resposta contém um token no campo client_token

Políticas restringem o acesso por caminho e operação:

path "secret/data/producao/*" {
  capabilities = ["read"]
}

path "secret/data/homologacao/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

4. Armazenamento e Rotação de Segredos

O Vault oferece dois tipos principais de segredos:

  • KV (Key-Value): armazenamento estático de pares chave-valor
  • Segredos dinâmicos: gerados sob demanda com TTL configurável

Para bancos de dados, o Vault pode gerar credenciais temporárias:

# Habilitar engine de banco PostgreSQL
vault secrets enable database

# Configurar conexão
vault write database/config/postgres \
  plugin_name=postgresql-database-plugin \
  allowed_roles="my-role" \
  connection_url="postgresql://{{username}}:{{password}}@localhost:5432/mydb"

# Criar role com TTL de 1 hora
vault write database/roles/my-role \
  db_name=postgres \
  creation_statements="CREATE USER \"{{name}}\" WITH PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  default_ttl="1h" \
  max_ttl="24h"

Para gerar um segredo dinâmico:

vault read database/creds/my-role

A resposta inclui nome de usuário, senha e TTL. O Vault revoga automaticamente a credencial no final do TTL.

5. Integração com Aplicações em Produção

A leitura de segredos via API é simples e direta:

# Com token válido
curl --header "X-Vault-Token: s.your-token-here" \
  http://vault:8200/v1/secret/data/myapp/database

Em Python, usando a biblioteca oficial:

import hvac

client = hvac.Client(url='http://vault:8200', token='s.your-token')
read_response = client.secrets.kv.read_secret_version(
    path='myapp/database',
    mount_point='secret'
)
print(read_response['data']['data'])

Boas práticas na integração:

  • Cache local: armazene segredos em memória por até 75% do TTL
  • Tratamento de erros: implemente retry com backoff exponencial
  • Renovação automática: use bibliotecas que renovam tokens antes da expiração

6. Estratégias de Selo e Recuperação

O selo (seal) protege a chave mestra do Vault. Quando o servidor inicia, ele está "selado" e não pode descriptografar dados. É necessário "deselar" fornecendo chaves de desbloqueio.

Em produção, o Auto Unseal é recomendado:

# Configuração do Auto Unseal com AWS KMS
seal "awskms" {
  region     = "us-east-1"
  kms_key_id = "1234abcd-12ab-34cd-56ef-1234567890ab"
}

Para recuperação de desastres, mantenha chaves de recuperação em local seguro (cofre físico, gerenciador de senhas corporativo). Configure replicação entre clusters para alta disponibilidade.

7. Monitoramento e Auditoria

O Vault registra cada operação em logs de auditoria:

# Habilitar auditoria em arquivo
vault audit enable file file_path=/var/log/vault/audit.log

Exemplo de log de auditoria:

{
  "time": "2024-01-15T10:30:00Z",
  "type": "response",
  "auth": {
    "client_token": "hmac-sha256:...",
    "policies": ["myapp-policy"]
  },
  "request": {
    "path": "secret/data/myapp/database",
    "operation": "read"
  },
  "response": {
    "data": {
      "data": {
        "password": "hmac-sha256:..."
      }
    }
  }
}

Métricas podem ser exportadas para Prometheus:

# Habilitar métricas Prometheus
vault write sys/metrics/config prometheus=true

Alerta para selo fechado ou tentativas de acesso não autorizado:

# Alerta Prometheus (exemplo)
- alert: VaultSealed
  expr: vault_core_unsealed == 0
  for: 5m
  annotations:
    summary: "Vault está selado"

8. Boas Práticas e Armadilhas Comuns

Nunca exponha tokens de root em produção. Use AppRole ou Kubernetes auth para autenticação de aplicações.

Prefira segredos dinâmicos sempre que possível. Eles eliminam o risco de credenciais vazadas que nunca expiram.

Teste a política de renovação e revogação em staging antes de ir para produção. Simule falhas de rede, expiração de tokens e indisponibilidade do Vault.

Armadilhas comuns:
- Tokens com TTL muito longo (dias) sem renovação adequada
- Políticas muito permissivas (wildcard excessivo)
- Ignorar logs de auditoria
- Não configurar Auto Unseal em produção

Referências