Closed YahavGB closed 3 years ago
After some more debugging, I could get rid of this log by doing
leaseContainer.removeLeaseErrorListener(SecretLeaseEventPublisher.LoggingErrorListener.INSTANCE);
That's being said, I still doubt that it should be the default behavior, as the rotation of an expired key should be transparent and shouldn't raise an error. WDYT?
Spring Vault supports credential rotation, it's the current relationship between Spring Boot and connection resources that does not support rotation for all supported configurations. Manual rotation is fine if you're propagating credentials yourself to the target (connection pool, driver, …).
lease not found
should actually not happen, it should be guarded by the min-renewal threshold (defaulting to 10 seconds) that prevents short-lived leases from being renewed. Since your lease duration is 10 seconds, you get hit by the expiry threshold underrun. Spring Vault has no chance to renew the lease because the default is higher than your lease duration.
So from that perspective, the reported log event is perfectly fine because it hints you at a problem that can be solved by increasing the lease duration for the configured role.
Hi!
Describe the bug I've started to integrate the HashiCorp Vault with my Spring-based project. My Vault configuration:
path "sys/renew/database/creds/*" { capabilities = ["read", "update", "list"] }
path "sys/leases/*" { capabilities = ["create", "read", "update", "delete", "list"] }
path "auth/token/renew-self" { capabilities = ["read", "update", "list"] }
spring: application: name: app cloud: vault: application-name: app authentication: APPROLE host: ${VAULT_HOST:localhost} port: ${VAULT_PORT:8200} app-role: role-id: ${VAULT_APP_ROLE_ID} secret-id: ${VAULT_APP_ROLE_SECRET_ID} scheme: http database: enabled: true role: db-role kv: enabled: true default-context: app application-name: app
spring: datasource: url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME}?characterEncoding=UTF-8&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver
@Slf4j @RequiredArgsConstructor @Configuration public class VaultLeaseConfig { @Value("${spring.cloud.vault.database.role}") private String databaseRole;
private final ApplicationContext applicationContext; private final SecretLeaseContainer leaseContainer;
@PostConstruct private void postConstruct() { final String vaultCredsPath = String.format("database/creds/%s", databaseRole);
}
private void updateDataSource(String username, String password) { HikariDataSource hikariDataSource = (HikariDataSource) applicationContext.getBean("dataSource");
}
}
2020-10-16 23:46:44.404 INFO [app,,,] 64810 --- [g-Cloud-Vault-1] i.p.h.a.configurations.VaultLeaseConfig : ==> Received event: org.springframework.vault.core.lease.event.SecretLeaseCreatedEvent[source=RequestedSecret [path='database/creds/db-role', mode=ROTATE]] 2020-10-16 23:46:45.088 INFO [app,,,] 64810 --- [g-Cloud-Vault-1] i.p.h.a.configurations.VaultLeaseConfig : ==> Update System properties username & password 2020-10-16 23:46:45.088 INFO [app,,,] 64810 --- [g-Cloud-Vault-1] i.p.h.a.configurations.VaultLeaseConfig : ==> spring.datasource.username: v-app-f04R8KXmVMQ 2020-10-16 23:46:45.088 INFO [app,,,] 64810 --- [g-Cloud-Vault-1] i.p.h.a.configurations.VaultLeaseConfig : ==> Soft evict database connections 2020-10-16 23:46:45.088 DEBUG [app,,,] 64810 --- [nnection closer] com.zaxxer.hikari.pool.PoolBase : Hikari - Closing connection com.mysql.cj.jdbc.ConnectionImpl@59d9d656: (connection evicted) 2020-10-16 23:46:45.089 INFO [app,,,] 64810 --- [g-Cloud-Vault-1] i.p.h.a.configurations.VaultLeaseConfig : ==> Update database credentials 2020-10-16 23:46:45.089 INFO [app,,,] 64810 --- [g-Cloud-Vault-1] i.p.h.a.configurations.VaultLeaseConfig : ==> DONE updateDataSource 2020-10-16 23:46:45.089 INFO [app,,,] 64810 --- [g-Cloud-Vault-1] i.p.h.a.configurations.VaultLeaseConfig : ==> DONE HANDLE event: org.springframework.vault.core.lease.event.SecretLeaseCreatedEvent[source=RequestedSecret [path='database/creds/db-role', mode=ROTATE]] 2020-10-16 23:46:45.090 WARN [app,,,] 64810 --- [g-Cloud-Vault-1] LeaseEventPublisher$LoggingErrorListener : [RequestedSecret [path='database/creds/db-role', mode=ROTATE]] Lease [leaseId='database/creds/db-role/qWnW8gCOCQjnmoFHU8I8sdlp', leaseDuration=PT10S, renewable=true] Cannot renew lease: Status 400 Bad Requestlease not found; nested exception is org.springframework.vault.VaultException: Status 400 Bad Request: lease not found; nested exception is org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: [{"errors":["lease not found"]} ]
org.springframework.vault.VaultException: Cannot renew lease: Status 400 Bad Requestlease not found; nested exception is org.springframework.vault.VaultException: Status 400 Bad Request: lease not found; nested exception is org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: [{"errors":["lease not found"]} ] at org.springframework.vault.core.lease.SecretLeaseContainer.doRenewLease(SecretLeaseContainer.java:713) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.lease.SecretLeaseContainer.renewAndSchedule(SecretLeaseContainer.java:589) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.lease.SecretLeaseContainer.lambda$scheduleLeaseRenewal$0(SecretLeaseContainer.java:581) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.lease.SecretLeaseContainer$LeaseRenewalScheduler$1.run(SecretLeaseContainer.java:891) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na] at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) ~[na:na] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:na] at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] Caused by: org.springframework.vault.VaultException: Status 400 Bad Request: lease not found; nested exception is org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: [{"errors":["lease not found"]} ] at org.springframework.vault.client.VaultResponses.buildException(VaultResponses.java:63) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.VaultTemplate.doWithSession(VaultTemplate.java:391) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.lease.SecretLeaseContainer.doRenew(SecretLeaseContainer.java:751) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.lease.SecretLeaseContainer.doRenewLease(SecretLeaseContainer.java:688) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] ... 12 common frames omitted Caused by: org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: [{"errors":["lease not found"]} ] at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:101) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:184) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:125) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:782) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:740) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:583) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] at org.springframework.vault.core.lease.LeaseEndpoints$1.renew(LeaseEndpoints.java:59) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.lease.SecretLeaseContainer.lambda$doRenew$2(SecretLeaseContainer.java:752) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] at org.springframework.vault.core.VaultTemplate.doWithSession(VaultTemplate.java:388) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE] ... 14 common frames omitted