Spring cloud vault not reloading/reflecting updates to secret value - spring

Spring cloud vault picks up the latest secret value during application start. If the secret is updated when the application is already up and running, then it is not picked up.
I understand this is a Spring config limitation and there is a workaround with the #RefreshScope annotation and explicitly invoking the /actuator/refresh API.
Is there any other mechanism where the application can listen to secret update notifications and automate the refresh?
From the debug logs, I see that the spring cloud vault returns an updated secret with the GET call based on "min-renewal" time.

Got 'refresh' working with:
#Autowired
ContextRefresher contextRefresher;
public void refreshContext() {
contextRefresher.refresh();
}
I am still trying to understand why spring cloud vault invokes vault login and Get API every 10 seconds if the refresh is not automated.

Related

Spring Cloud GCP Starter Authentication Issues

I am using spring-cloud-gcp-starter,spring-cloud-gcp-starter-pubsub,spring-cloud-gcp-starter-data-datastore for the autoconfiguration of my gcp dependencies.
It fetches the key from system variable:: spring.cloud.gcp.credentials.encoded-key
which I am setting in my configuration class as System.setProperty("spring.cloud.gcp.credentials.encoded-key","privatevalue");
There is a case where my key will be rotated every x days and I want to ensure that my application gives me authorization when the key rotates.
One way I have thought is to overwrite the system variable when my key rotates but how do we make sure gcp uses the latest key for authentication or will this approach work?.
I looked at the CredentialsProvider class and it seems they only have getter method and setter is handled via autoconfiguration.
You are right that CredentialsProvider bean in spring-cloud-gcp is created in autoconfiguration.
In Spring Cloud ecosystem, you can refresh configuration by using #RefreshScope. So then all configurations in this scope will get refreshed when the /refresh endpoint is hit. Read more in spring documentation here.
For rotating the keys, you can override the CredentialsProvider bean in your configuration with #RefreshScope, so that you can refresh your keys without restarting the application.
You can refer to how it is done in this sample application.

Accessing GCP secret key with /actuator/refresh endpoint in spring boot

I am accessing GCP secret key in Spring boot config Server / Client with 'sm://' and it's working perfectly when application started.
Now I am invoking '/actuator/refresh' endpoint.. here application failed to bind the property specified for secret key with sm:// prefix.
However, if I provide plain text, that works fine; so issue is accessing secret key from Google cloud.
Can anyone help me on the same !
Thanks
Unfortunately, it is not possible to refresh or load secrets using the actuator/refresh endpoint due to limitations with Spring (specifically the mechanism called "bootstrap loading" which is how the secrets are loaded by the .properties files.).
Details are provided here: https://github.com/spring-cloud/spring-cloud-gcp/issues/2485

Is Service binding approach using spring cloud connectors relevant when credentials are stored in Vault?

I have been using the Spring cloud Service connectors for Pivotal cloud foundry for a long time which gets the connection details from the VCAP_SERVICES env variable. Now we have a requirement to read these credentials from Vault . I am just curious , Can I still continue to use the Service binding approach with spring cloud connector ? I would assume we don't want to expose these credentials from vault to an VCAP_SERVICES variable which defeat the purpose of the vault. Has there been any enhancements in Spring cloud connectors to read the credentials directly from Vault rather than depending the VCAP_SERVICES env variable or should I resort back to the Spring boot's default Application Properties based approach instead of the service binding approach using cloud connectors ?
The Spring Cloud Connectors project is now in maintenance mode, in favor of the newer Java CFEnv project. However, Java CFEnv is also very specific to Cloud Foundry's VCAP_SERVICES model of exposing service bindings and won't help you if the service connection info is in Vault.
I would suggest that you fall back to the Spring Boot properties-based approach using Spring Cloud Vault or Spring Cloud Config Server's Vault integration to automate fetching the properties from Vault and making them available as Spring Boot properties.

Automatically renew AWS credentials in a Spring Boot application using Spring Cloud Vault

I'm trying to create a Spring Boot application that regularly fetch data from AWS S3.
The AWS S3 credentials are fetched from Vault using Spring Cloud Vault when the application start.
My issue is that AWS S3 credentials have a limited lifespan due to Vault policy so I have to restart my application from time to time to obtain new credentials from Vault
Is there a way to automatically restart bean using those credentials?
TL;DR
No, there is no automatism, but you can do this yourself.
The longer read
Spring Boot and Spring Cloud aren't really intended for applying continuous updates to the configuration without interruption. Spring Cloud Config ships with Refresh Scope support that allows to annotate beans with #RefreshScope and trigger a refresh of the beans that get re-initialized. This approach requires either integration with a message bus or triggering the refresh endpoint.
The other alternative, which is limited to AWS functionality, is providing an own AWSCredentialsProvider implementation that is backed by a Vault PropertySource that applies rotation to your credential. This requires you to provide a bit of code that integrates with VaultConfigurer or even directly via SecretLeaseContainer to get secret lifecycle event callbacks. See here for an integration example.
There is a ticket asking for the same question that contains background why this pattern isn't widely applicable.

Spring Cloud Security JWT: Distribute Public Key using Config Server / Key Rotation

How do you manage your Private / Public Keys for signing / validating JWTs in Spring Cloud environment?
The "problem":
At the moment I generate a Key Pair. Then copy Private + Public Key to my auth-server application. And also copy the Public Key to each and every Resource Server.
When I now want to implement "Key Rotation" I have to somehow populate the new keys to every service.
The idea:
Maybe I could use the spring-cloud-config-server to store and distribute the Key Pairs?
The config server already provides database login credentials. So why not store even more sensitive information there?
Question(s):
If this is the way to go: How would you implement the key pair distribution with spring-cloud-config-server?
Do you have any security concerns?
How did you solve this problem? I guess there are better solutions.
EDIT:
Maybe there's some solution using Spring Oauth's security.oauth2.resource.jwt.keyUri property for JWKs?
First of all, I would had a gateway to hide the JWT mechanism. It will allow you to revoke tokens from the gateway. If an user know about his token, you can't revoke it without revoke the public key. It will look like this :
It's easy to implement with zuul's filters and session-scoped beans.
Secondly, has you said it in comments, you can simply create a new private key to generate new tokens. But all your resource servers must be able to read all the previously generated tokens. So you need to have a list of public key on each resource servers, and each time you receive a request, you must try to verify it with each public key. Maybe you can had a public key id (and put the id on each generated token) to avoid to do dumb look for this task.
For key distribution, use spring cloud bus and rabbit mq seems right to me.
You should consider the use of Spring Cloud Consul Config instead:
Consul provides a Key/Value Store for storing configuration and other
metadata. Spring Cloud Consul Config is an alternative to the Config
Server and Client. Configuration is loaded into the Spring Environment
during the special "bootstrap" phase. Configuration is stored in the
/config folder by default. Multiple PropertySource instances are
created based on the application’s name and the active profiles that
mimicks the Spring Cloud Config order of resolving properties.
You can POST to /refresh to update your key, or watch for changes:
The Consul Config Watch takes advantage of the ability of consul to
watch a key prefix. The Config Watch makes a blocking Consul HTTP API
call to determine if any relevant configuration data has changed for
the current application. If there is new configuration data a Refresh
Event is published.

Resources