Access vault secret using spring-cloud-vault and use it in application.properties - spring

I have a vault server hosted in Openshift and I have to access secrets from the Vault into my spring application.
My bootstrap.yml looks like this :
spring:
application:
name: application-name
profiles: dev
cloud:
vault:
fail-fast: true
host: HOST
port: 443
scheme: https
token: MY_TOKEN
authentication: TOKEN
kv:
enabled: true
backend: secret
profile-separator: '/'
application-name: application-name
I checked vault logs and able to make connection from spring application to vault.
I can access the secret using Value Property Source.
However, I want to populate the secret's value into application.properties to update properties like spring.datasource.username and spring.datasource.password.
Is there any way to access the secret directly from application.properties?

TL; DR: Yes, you can use Vault properties in application.(properties|yml). It's not recommended to use these in bootstrap.(properties.yml).
Spring Cloud comes with a Bootstrap context where configuration libraries (such as Spring Cloud Consul, Spring Cloud Config and Spring Cloud Vault) are initialized. These integrations fetch configuration and provide these as a parent PropertySources to your application. Spring Boot considers these (you have options to use these PropertySources with the highest/lowest priority) during property binding and when you resolve a property value using Environment.
When bootstrapping an application, then typically one of the first things that happen is property binding in #ConfigurationProperties objects. At the time when bootstrap.(properties|yml) is loaded, typically Spring Cloud Config integrations didn't run yet so at that time you don't see properties contributed by these libraries. Therefore, there's the split between bootstrap context and the actual application context.

Related

Spring cloud config server for multiple stage

I'm working with spring cloud config server, and my need is to create a configuration file for each stage prod test and dev, I already created 4 yml file application.yml for the default profile, application-{profiles} for each profile, so my question is how to load the specific configuration through the environment variable and run the config server on each profile configuration and port , I already created a bootstrap.yml but I can't solve the issue.
I will be very thankful if someone can guide throught the steps to achieve my need.
You don't need to start Spring Cloud Config Server with different profiles and on different port per environment. You can have one Config Server that manages the configurations for all environments. In your client's bootstrap.yml you will need to provide the URL of your Config Server as follows:
spring:
cloud:
config:
uri: http://your-config-server
When you run your client application with a particular profile (e.g. via an environment variable spring_profiles_active=dev), Spring Cloud Config Client will fetch the configuration properties from Config Server for the targeted profile.
I recommend to review at least the Quick Start section of the Spring Cloud Config documentation and try the examples provides there.

How to test application yml resource file settings that uses Spring Boot?

For example, I have settings like code below which Spring Boot Actuator uses.
management:
server:
port: 60001
security:
enabled: false
And I found out that if I will write this setting with mistakes. For example (code below):
management:
server:
port: 60001
security:
enabled: fase # wrong typed a `false` word
Spring Boot will not do anything, and the application will have build successfully.
Spring boot will validate the data as long as #ConfigurationProperties exist in core. The problem is that your #ConfigurationProperties may not exist before or already deprecated in your spring boot version.
Below is the comparison of management.server class with #ConfigurationProperties.
Try to change the port with string and spring boot with validate the data.
Look also at ManagementContextAutoConfiguration.class if your using spring boot 2 you will see that it loads the class ManagementServerProperties and WebEndpointProperties
If you still needed to validate your yaml you can refer to SnakeYAML.

Spring Cloud Config - Store info in vault (Username/pwd) along with rest of propeties in Git

We are right now storing passwords and other configuration related data in git and filesystem(local) based on profile. This is working fine based on profiles local/dev etc. using SPring cloud config approach.
But to enhance security we have been suggested to use sensitive data in Vault
So i am not clear on how can this be achieved. Whether we will have a single Cloud Config server hosting some properties from Vault and some from Git.
A Config Client will locate the config server based on CONFIGSERVER_URI so we can not have separate instances running
How to achieve this requirement.
Thanks.
It is possible to access Git for some properties and Vault for others using the same config server. Access to Vault locations is granted to individual client through the use of a Vault token. The Vault token is passed automatically to the config server as a header at runtime. You would need to configure your config server with the Vault dependencies and add properties to access both Git and Vault something like this (not the 'vault' profile):-
server:
port: 8888
spring:
profiles:
active: git, vault
application:
name: my-domain-configuration-server
cloud:
config:
server:
git:
uri: https://mygit/my-domain-configuration
order: 1
vault:
order: 2
host: vault.mydomain.com
port: 8200
scheme: https
On your client you need to configure the authorization token supplied by Vault. Note the example below illustrates the property. You can put it into your application yaml files, because it is a per application/per environment token. However I prefer to inject it into the environment during deployment.
spring:
cloud:
config:
uri: https://configserver:8888/
token: <secret token>
You should consult the Vault documentation to understand how to authorize your token to access specific locations but the rules may look something like this:-
{
path "secret/myapp-app" {
policy = "read"
}
path "secret/myapp-app/*" {
policy = "read"
}
path "secret/application" {
policy = "read"
}
path "secret/application/*" {
policy = "read"
}"
}
Finally, it is also possible to access your Git through config server and access Vault directly from your client instead of configuring config server to access both. In this case you need to add the Vault dependencies to the client and configure the client properties to access Vault. You still need the authorization token in the client.

bootstrap.yml and AWS user data

I have Spring Boot based application deployed to AWS EC2 instances. The application is a Spring Cloud Config Client.
I would like to configure the URL to my Spring Cloud Config Server via AWS user data (using Spring Cloud AWS).
I can already access the user data via #Value annotations. However if I try to refer to user data inside bootstrap.yml, it's not able to resolve it.
spring:
application:
name: network-device-service
cloud:
config:
uri: ${SPRING_CONFIG_URI}
Any ideas if this it at all possible in bootstrap.yml?

Is there a way to use Spring Cloud {cipher} in Spring Boot application config?

I have a Spring Boot app that is using Spring Cloud Config but I would like to encrypt the Spring Cloud Config password in the Spring Boot apps bootstrap.yml file. Is there a way to do this? Below is an example.
Spring Boot app bootstrap.yml
spring:
cloud:
config:
uri: http://locahost:8888
username: user
password: '{cipher}encryptedpassword'
A couple things I've discovered related to this.
If you use bootstrap.yml (or application.yml), the format for the cipher text must enclosed within single quotes:
security.user.password: '{cipher}56e611ce4a99ffd99908d2c9aa1461d831722812e4370a5b6900b7ea680ae914'
If you use bootstrap.properties (or application.properties), the format for the cipher text must NOT be enclosed:
security.user.password= {cipher}56e611ce4a99ffd99908d2c9aa1461d831722812e4370a5b6900b7ea680ae914
The [reference docs][1] show the yml without the quotes, which I never got to work. SnakeYaml always reported an error:
"expected <block end>, but found Scalar"
There is support for encrypted properties in the config client (as described in the user guide). Obviously if you do it that way you have to provide a key to decrypt the properties at runtime, so actually I don't always see the benefit (I suppose the config file is a bit like a keystore with a special format, so you only have one secret to protect instead of many). Example (application.yml):
integration:
stores:
test: '{cipher}316f8cdbb776c23e679bf209014788a6eab7522f48f97114328c2c9388e6b3c1'
and the key (in bootstrap.yml):
encrypt:
key: ${ENCRYPT_KEY:} # deadbeef
You can use Spring CLI to encrypt the secrets spring encrypt password --key 'SECRET_KEY'
https://cloud.spring.io/spring-cloud-cli/

Resources