spring-cloud / spring-cloud-vault

Configuration Integration with HashiCorp Vault
http://cloud.spring.io/spring-cloud-vault/
Apache License 2.0
270 stars 151 forks source link

Token rotation in the vault does not seem to trigger Refresh Event #724

Open pavelfomin opened 3 months ago

pavelfomin commented 3 months ago

Describe the bug When token in rotated in the vault, the property value is updated in the Spring Context Environment but the Refresh Event does not seem to be triggered. As the result, using @RefreshScope, @Value or @ConfigurationProperties does not work.

Sample Given vault config:

spring:
  cloud:
    vault:
      host: vault.some.com
      port: 8200
      scheme: https
      namespace: NM
      fail-fast: false
      authentication: APPROLE
      app-role:
        role-id: ${GCS_ROLE_ID}
        secret-id: ${GCS_SECRET_ID}
      enabled: true
      reactive:
        enabled: false
      config.lifecycle:
        enabled: true
        expiry-threshold: 2m

  config:
    import: vault://${GCS_VAULT}/static-account/${GCS_VAULT_ACCOUNT}/key?prefix=app.storage.credentials.

The following code is actually working:

@Configuration
@RequiredArgsConstructor
public class CredentialConfiguration {

    private final Environment environment;

    @SneakyThrows
    @Bean
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    GoogleCredentials fromServiceKey() {

        String privateKeyData = environment.getProperty("app.storage.credentials.private_key_data");
        var decoded = Base64.getDecoder().decode(privateKeyData);
        var stream = new ByteArrayInputStream(decoded);
        return ServiceAccountCredentials.fromStream(stream);
    }

However, if property is injected with @Value or @ConfigurationProperties, the old value assigned at the application startup is used even if @RefreshScope is added to the@Bean. And none of the beans annotated with @RefreshScope are recreated.

Expected behavior: when GET /v1/gcp-non-prod/static-account/svc-dev-rebatearc-gcs/key?prefix=app.storage.credentials. is invoked and a new value is received from the vault, the Refresh Event is published so any @Bean with @RefreshScope can be refreshed.