Uma introdução ao Spring Cloud Vault
1. Visão geral
Neste tutorial, mostraremos como podemos usar o Vault da Hashicorp em aplicativos Spring Boot para proteger dados de configuração confidenciais.
We assume here some Vault knowledge and that we have a test setup already up and running. Se este não for o caso, vamos ler nossoVault Intro tutorial para que possamos nos familiarizar com seus fundamentos.
2. Spring Cloud Vault
O Spring Cloud Vault é uma adição relativamente recente à pilha do Spring Cloud queallows applications to access secrets stored in a Vault instance in a transparent way.
Em geral, a migração para o Vault é um processo muito simples: basta adicionar as bibliotecas necessárias e adicionar algumas propriedades de configuração extras ao nosso projeto, e devemos estar prontos. No code changes are required!
Isso é possível porque atua como umPropertySource de alta prioridade registrado noEnvironment atual.
Como tal, o Spring o usará sempre que uma propriedade for necessária. Os exemplos incluem propriedadesDataSource,ConfigurationProperties, e assim por diante.
3. Adicionando o Spring Cloud Vault a um projeto do Spring Boot
Para incluir a bibliotecaspring-cloud-vault em um projeto Spring Boot baseado em Maven, usamos o artefatostarter associado, que extrairá todas as dependências necessárias.
Além dostarter, principal, também incluiremos ospring-vault-config-databases, que adiciona suporte para credenciais de banco de dados dinâmicas:
org.springframework.cloud
spring-cloud-starter-vault-config
org.springframework.cloud
spring-cloud-vault-config-databases
A versão mais recente doSpring Cloud Vault starter pode ser baixada do Maven Central.
3.1. Configuração básica
Para funcionar corretamente, o Spring Cloud Vault precisa de uma maneira de determinar onde entrar em contato com o servidor do Vault e como se autenticar nele.
Fazemos isso fornecendo as informações necessárias embootstrap.yml oubootstrap.properties:
# bootstrap.yml
spring:
cloud:
vault:
uri: https://localhost:8200
ssl:
trust-store: classpath:/vault.jks
trust-store-password: changeit
A propriedadespring.cloud.vault.uri aponta para o endereço da API do Vault. Como nosso ambiente de teste usa HTTPS com um certificado autoassinado, também precisamos fornecer um keystore contendo sua chave pública.
Note that this configuration has no authentication data. Para o caso mais simples, onde usamos um token fixo, podemos passá-lo pela propriedade do sistemaspring.cloud.vault.token ou uma variável de ambiente. Essa abordagem funciona bem em conjunto com mecanismos de configuração de nuvem padrão, como os segredos do ConfigMaps ou do Docker do Kubernetes.
O Spring Vault também requer configuração extra para cada tipo de segredo que queremos usar em nosso aplicativo. As seções a seguir descrevem como podemos adicionar suporte a dois tipos de segredo comuns: chave / valor e credenciais do banco de dados.
4. Usando o back-end de segredos genéricos
We use the Generic Secret backend to access unversioned secrets stored as Key-Value pairs in Vault.
Assumindo que já temos a dependênciaspring-cloud-starter-vault-config em nossoclasspath, tudo o que temos a fazer é adicionar algumas propriedades ao arquivo de configuraçãobootstrap.yml do aplicativo:
spring:
cloud:
vault:
# other vault properties omitted ...
generic:
enabled: true
application-name: fakebank
A propriedadeapplication-name é opcional neste caso. Se não for especificado, o Spring assumirá o valor do padrãospring.application.name.
Agora podemos usar todos os pares de chave / valor armazenados emsecret/fakebank como qualquer outra propriedadeEnvironment. O trecho a seguir mostra como podemos ler o valor da chavefoo armazenada em este caminho:
@Autowired Environment env;
public String getFoo() {
return env.getProperty("foo");
}
As we can see, the code itself knows nothing about Vault, o que é uma coisa boa! Ainda podemos usar propriedades fixas em testes locais e mudar para o Vault como quisermos, apenas habilitando uma única propriedade embootstrap.yml.
4.1. Uma nota sobre perfis de primavera
Se disponível no atualEnvironment, Spring Cloud Vaultwill use the available profile names as a suffix appended to the specified base path where key/value pairs will be searched.
Ele também procurará propriedades em um caminho de aplicativo padrão configurável (com e sem um sufixo de perfil) para que possamos compartilhar segredos em um único local. Use esse recurso com cuidado!
Para resumir, se o perfilproduction do aplicativofakebank estiver ativo, o Spring Vault irá procurar por propriedades armazenadas nos seguintes caminhos:
-
secret/fakebank_/production_ (higher priority)
-
secret/fakebank
-
secret/application/production
-
secret/application (prioridade inferior)
Na lista anterior,application é o nome que Spring usa como local adicional padrão para segredos. Podemos modificá-lo usando a propriedadespring.cloud.vault.generic.default-context.
As propriedades armazenadas no caminho mais específico terão precedência sobre as outras. Por exemplo, se a mesma propriedadefoo estiver disponível nos caminhos acima, a ordem de precedência seria:
5. Usando o backend secreto do banco de dados
The Database backend module allows Spring applications to use dynamically generated database credentials created by Vault. O Spring Vault injeta essas credenciais nas propriedadesspring.datasource.usernameespring.datasource.password padrão para que possam ser selecionadas porDataSources regulares.
Observe que, antes de usar este back-end, devemos criar uma configuração de banco de dados e funções no Vault conforme descrito emour previous tutorial.
Para usar as credenciais de banco de dados geradas pelo Vault em nosso aplicativo Spring, ospring-cloud-vault-config-databases deve estar presente no classpath do projeto, junto com o driver JDBC correspondente.
Também precisamos habilitar seu uso em nosso aplicativo adicionando algumas propriedades ao nossobootstrap.yml:
spring:
cloud:
vault:
# ... other properties omitted
database:
enabled: true
role: fakebank-accounts-rw
A propriedade mais importante aqui é a propriedaderole, que contém um nome de função de banco de dados armazenado no Vault. Durante a inicialização, o Spring entrará em contato com o Vault e solicitará que ele crie novas credenciais com os privilégios correspondentes.
Por padrão, o cofre revogará os privilégios associados a essas credenciais após o tempo de vida configurado.
Felizmente,Spring Vault will automatically renew the lease associated with the acquired credentials. Ao fazer isso, as credenciais permanecerão válidas enquanto nosso aplicativo estiver em execução.
Agora, vamos ver essa integração em ação. O seguinte snippet obtém uma nova conexão de banco de dados de umDataSource gerenciado por Spring:
Connection c = datasource.getConnection();
Once again, we can see that there is no sign of Vault usage in our code. Toda integração acontece no nívelEnvironment, então nosso código pode ser facilmente testado na unidade como de costume.
6. Conclusão
Neste tutorial, mostramos como integrar o Vault com Spring Boot usando a biblioteca Spring Vault. Cobrimos dois casos de uso comuns: pares de chave / valor genérico e credenciais de banco de dados dinâmicas.
Um projeto de amostra contendo todas as dependências necessárias, testes de integração e scripts de configuração de vault está disponívelover on GitHub.