HashiCorp Vault: Instalação, Configuração e Integração para Gerenciamento de Segredos

Introdução ao HashiCorp Vault e Gerenciamento de Segredos

O hashicorp vault é uma ferramenta centralizada para o gerenciamento de segredos em ambientes de TI modernos. Segredos são quaisquer informações sensíveis que precisam ser rigorosamente controladas e auditadas, como chaves de API, senhas de banco de dados, credenciais de nuvem, certificados TLS e chaves de criptografia. Em arquiteturas dinâmicas e distribuídas, como microsserviços e infraestrutura como código (IaC), o gerenciamento manual de segredos torna-se impraticável e inseguro.

O Vault resolve esse problema ao fornecer uma interface unificada para acessar segredos, aplicando políticas de acesso granulares e mantendo um log de auditoria detalhado de todas as interações. Ele criptografa os dados tanto em trânsito (usando TLS) quanto em repouso (usando um algoritmo como AES-GCM de 256 bits), garantindo que os segredos permaneçam protegidos mesmo que o storage backend seja comprometido.

Arquitetura e Conceitos Fundamentais do Vault

Antes de prosseguir com a instalação, é crucial entender os componentes e conceitos que formam a base do Vault:

  • Storage Backend: O Vault não armazena dados por si só; ele utiliza um backend de armazenamento para persistir os dados criptografados. As opções incluem Consul, etcd, PostgreSQL, S3, entre outros. O backend nunca vê os dados em seu formato original (plaintext).
  • Secrets Engines: São componentes responsáveis por gerenciar diferentes tipos de segredos. Existem engines para segredos estáticos (como o KV – Key/Value), segredos dinâmicos (credenciais de banco de dados ou cloud geradas sob demanda com tempo de vida limitado) e serviços de criptografia (transit engine).
  • Auth Methods: Definem como os clientes (usuários, aplicações, máquinas) se autenticam no Vault para provar sua identidade. Exemplos incluem tokens, username/password, AppRole, Kubernetes, AWS IAM e certificados.
  • Policies: Após a autenticação, as políticas (policies) determinam quais ações um cliente autenticado pode realizar. Elas são escritas em HCL (HashiCorp Configuration Language) e seguem um modelo de negação por padrão (deny-by-default).
  • Seal/Unseal: Quando o Vault é iniciado, ele começa em um estado selado (sealed). Nesse estado, ele conhece a localização do storage backend, mas não sabe como descriptografar os dados. O processo de “unseal” consiste em fornecer um conjunto de chaves (unseal keys) para reconstruir a chave mestra (master key) em memória, permitindo que o Vault descriptografe os dados e comece a atender requisições.

Instalação do Vault em Modo de Desenvolvimento

Para fins de aprendizado e desenvolvimento local, o Vault pode ser executado em modo de desenvolvimento. Este modo simplifica a inicialização, usando um storage backend em memória e realizando o unseal automaticamente. Atenção: não utilize este modo em produção.

Passo 1: Download e Instalação

O Vault é distribuído como um único binário. Baixe o pacote apropriado para o seu sistema operacional no site oficial da HashiCorp. Após o download, descompacte o arquivo e mova o binário `vault` para um diretório em seu `PATH` (como `/usr/local/bin` em sistemas Linux/macOS).

# Exemplo para Linux 64-bit
wget https://releases.hashicorp.com/vault/1.15.2/vault_1.15.2_linux_amd64.zip
unzip vault_1.15.2_linux_amd64.zip
sudo mv vault /usr/local/bin/

Verifique a instalação executando:

vault --version

Passo 2: Iniciando o Servidor de Desenvolvimento

Execute o seguinte comando para iniciar o servidor em modo dev:

vault server -dev

O terminal exibirá informações importantes, incluindo o endereço do Vault (geralmente `http://127.0.0.1:8200`), a Unseal Key (apenas para referência no modo dev) e, mais importante, o Root Token. Este token concede permissões de superusuário. Guarde-o para os próximos passos.

Abra um novo terminal e configure as variáveis de ambiente para que o cliente CLI do Vault possa se comunicar com o servidor:

export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='s.yourRootTokenHere'

Verifique o status do servidor:

vault status

A saída deve indicar `Sealed: false` e `Initialized: true`.

Inicialização e Processo de Unseal (Modo Produção)

Em um ambiente de produção, o processo é manual e mais seguro. Primeiro, crie um arquivo de configuração `config.hcl`:

# Exemplo de config.hcl com storage backend de filesystem
storage "file" {
  path = "/opt/vault/data"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = "true" # Desabilitado para tutorial, sempre use TLS em produção
}

ui = true

Inicie o servidor com o arquivo de configuração:

vault server -config=config.hcl

Neste momento, o Vault está inicializado, mas selado. Em outro terminal, configure a variável `VAULT_ADDR` e execute o comando de inicialização:

export VAULT_ADDR='http://127.0.0.1:8200'
vault operator init

Este comando gera 5 Unseal Keys e 1 Initial Root Token. É crucial armazenar essas chaves de forma segura e distribuída entre diferentes pessoas. Para fazer o unseal do Vault, são necessárias 3 das 5 chaves (este é o padrão, pode ser configurado).

Execute o comando `vault operator unseal` três vezes, inserindo uma chave diferente em cada vez:

vault operator unseal <Unseal Key 1>
vault operator unseal <Unseal Key 2>
vault operator unseal <Unseal Key 3>

Após a terceira chave, o Vault estará operacional (`Sealed: false`). Agora, você pode fazer login com o Root Token inicial.

vault login <Initial Root Token>

Configurando Secrets Engines: KV e Database

Com o Vault operacional, podemos começar a gerenciar segredos. Vamos habilitar e configurar dois dos mais comuns secrets engines.

Key/Value (KV) v2 Secrets Engine

O engine KV v2 permite armazenar segredos estáticos com versionamento. Habilite-o em um caminho específico:

vault secrets enable -path=secret kv-v2

Agora, vamos escrever um segredo:

vault kv put secret/myapp/database username=db_user password=SuperSecretPassword123

Para ler o segredo:

vault kv get secret/myapp/database

A versão v2 permite visualizar versões anteriores e até mesmo recuperar segredos deletados (undelete), adicionando uma camada extra de segurança e controle.

Database Secrets Engine

Este engine gera dinamicamente credenciais de banco de dados com tempo de vida (TTL) limitado. Isso minimiza o risco de credenciais vazadas, pois elas expiram automaticamente.

Primeiro, habilite o engine:

vault secrets enable database

Em seguida, configure a conexão com o banco de dados (exemplo com PostgreSQL):

vault write database/config/my-postgresql 
    plugin_name=postgresql-database-plugin 
    allowed_roles="my-app-role" 
    connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb?sslmode=disable" 
    username="vault_admin" 
    password="vault_admin_password"

Finalmente, defina um “role” que mapeia para permissões no banco. Este role especifica os comandos SQL para criar e revogar usuários:

vault write database/roles/my-app-role 
    db_name=my-postgresql 
    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, uma aplicação pode solicitar credenciais temporárias:

vault read database/creds/my-app-role

O Vault se conectará ao banco, criará um novo usuário com as permissões definidas e retornará as credenciais. Ao final do TTL, o Vault revogará automaticamente essas credenciais.

Autenticação e Políticas de Acesso (ACLs)

O uso do Root Token deve ser restrito a configurações iniciais. Para o dia a dia, devemos criar políticas e usar métodos de autenticação apropriados para cada cliente.

Criando uma Política

Vamos criar uma política que concede permissão de leitura ao segredo do banco de dados que criamos anteriormente. Crie um arquivo `myapp-policy.hcl`:

# Concede permissão de leitura ao caminho do segredo da aplicação
path "secret/data/myapp/database" {
  capabilities = ["read"]
}

# Concede permissão para solicitar credenciais de banco de dados
path "database/creds/my-app-role" {
    capabilities = ["read"]
}

Carregue a política no Vault:

vault policy write myapp-policy myapp-policy.hcl

Configurando o Auth Method AppRole

O método AppRole é ideal para autenticação de máquinas e aplicações. Ele utiliza um `RoleID` (identificador do papel) e um `SecretID` (senha) para autenticar.

Habilite o método de autenticação AppRole:

vault auth enable approle

Crie um papel chamado `my-app` associado à política que acabamos de criar:

vault write auth/approle/role/my-app token_policies="myapp-policy" token_ttl="1h"

Obtenha o `RoleID`:

vault read auth/approle/role/my-app/role-id

Gere um `SecretID` para este papel:

vault write -f auth/approle/role/my-app/secret-id

O `RoleID` pode ser considerado público, enquanto o `SecretID` deve ser injetado na aplicação de forma segura (por exemplo, via um orchestrator como Kubernetes ou um script de provisionamento).

Integração com uma Aplicação

Com a política e o AppRole configurados, uma aplicação pode se autenticar e obter os segredos de que precisa. A maioria das linguagens de programação possui bibliotecas cliente para interagir com o Vault.

O fluxo geral para uma aplicação é:

  1. A aplicação é iniciada com o `RoleID` e o `SecretID` disponíveis (ex: via variáveis de ambiente).
  2. A aplicação faz uma chamada à API do Vault (endpoint `/v1/auth/approle/login`) enviando o `RoleID` e `SecretID`.
  3. O Vault valida as credenciais e retorna um token de cliente com as políticas associadas (`myapp-policy`).
  4. A aplicação utiliza este token para fazer requisições subsequentes aos caminhos de segredos permitidos pela política (ex: `secret/data/myapp/database` ou `database/creds/my-app-role`).
  5. O token possui um TTL. A biblioteca cliente é responsável por renovar o token antes que ele expire para manter a sessão ativa.

Este modelo desacopla a aplicação da gestão direta de segredos. A aplicação só precisa saber como se autenticar no Vault; o Vault, por sua vez, gerencia centralmente a rotação, o acesso e a auditoria de todos os segredos.