-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support any dynamic credentials in VaultCredentialsProvider
This change is in preparation of support for dynamic Vault credentials for RabbitMQ. It renames the "database" dynamic credentials supports to use "dynamic" in the names in an effort to be clear about its use. Vault dynamic credentials all have basicallly identical responses so the credentials provider should support any of them easily. This does essentially 3 things. 1. Renames `VaultDatabaseCredentials`, `VaultDBManager` and supporting classes to use the naming "Dynamic" 2. Adds a `VaultDynamicCredentialsType` enum (to determine plugin mount) and adds this as a parameter to `VaultDynamicCredentialsManager.getDynamicCredentials` 3. Adds an `expires-at` property to the returned credentials which is calculated from the Vault lease duration.
- Loading branch information
Showing
15 changed files
with
241 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 0 additions & 7 deletions
7
.../src/main/java/io/quarkus/vault/runtime/client/dto/database/VaultDatabaseCredentials.java
This file was deleted.
Oops, something went wrong.
10 changes: 0 additions & 10 deletions
10
.../main/java/io/quarkus/vault/runtime/client/dto/database/VaultDatabaseCredentialsData.java
This file was deleted.
Oops, something went wrong.
7 changes: 7 additions & 0 deletions
7
...el/src/main/java/io/quarkus/vault/runtime/client/dto/dynamic/VaultDynamicCredentials.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.quarkus.vault.runtime.client.dto.dynamic; | ||
|
||
import io.quarkus.vault.runtime.client.dto.AbstractVaultDTO; | ||
|
||
public class VaultDynamicCredentials extends AbstractVaultDTO<VaultDynamicCredentialsData, Object> { | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
...rc/main/java/io/quarkus/vault/runtime/client/dto/dynamic/VaultDynamicCredentialsData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package io.quarkus.vault.runtime.client.dto.dynamic; | ||
|
||
import io.quarkus.vault.runtime.client.dto.VaultModel; | ||
|
||
public class VaultDynamicCredentialsData implements VaultModel { | ||
|
||
public String username; | ||
public String password; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 0 additions & 124 deletions
124
extensions/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultDbManager.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
.../vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultDynamicCredentialsManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package io.quarkus.vault.runtime; | ||
|
||
import static io.quarkus.credentials.CredentialsProvider.EXPIRATION_TIMESTAMP_PROPERTY_NAME; | ||
import static io.quarkus.credentials.CredentialsProvider.PASSWORD_PROPERTY_NAME; | ||
import static io.quarkus.credentials.CredentialsProvider.USER_PROPERTY_NAME; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import javax.inject.Singleton; | ||
|
||
import org.jboss.logging.Logger; | ||
|
||
import io.quarkus.vault.runtime.client.VaultClientException; | ||
import io.quarkus.vault.runtime.client.backend.VaultInternalSystemBackend; | ||
import io.quarkus.vault.runtime.client.dto.sys.VaultRenewLease; | ||
import io.quarkus.vault.runtime.client.secretengine.VaultInternalDynamicCredentialsSecretEngine; | ||
import io.quarkus.vault.runtime.config.VaultBootstrapConfig; | ||
|
||
@Singleton | ||
public class VaultDynamicCredentialsManager { | ||
|
||
private static final Logger log = Logger.getLogger(VaultDynamicCredentialsManager.class.getName()); | ||
|
||
private ConcurrentHashMap<String, VaultDynamicCredentials> credentialsCache = new ConcurrentHashMap<>(); | ||
private VaultAuthManager vaultAuthManager; | ||
private VaultConfigHolder vaultConfigHolder; | ||
private VaultInternalSystemBackend vaultInternalSystemBackend; | ||
private VaultInternalDynamicCredentialsSecretEngine vaultInternalDynamicCredentialsSecretEngine; | ||
|
||
public VaultDynamicCredentialsManager(VaultConfigHolder vaultConfigHolder, VaultAuthManager vaultAuthManager, | ||
VaultInternalSystemBackend vaultInternalSystemBackend, | ||
VaultInternalDynamicCredentialsSecretEngine vaultInternalDynamicCredentialsSecretEngine) { | ||
this.vaultConfigHolder = vaultConfigHolder; | ||
this.vaultAuthManager = vaultAuthManager; | ||
this.vaultInternalSystemBackend = vaultInternalSystemBackend; | ||
this.vaultInternalDynamicCredentialsSecretEngine = vaultInternalDynamicCredentialsSecretEngine; | ||
} | ||
|
||
VaultDynamicCredentials getCachedCredentials(VaultDynamicCredentialsType type, String role) { | ||
return credentialsCache.get(type + "@" + role); | ||
} | ||
|
||
void putCachedCredentials(VaultDynamicCredentialsType type, String role, VaultDynamicCredentials credentials) { | ||
credentialsCache.put(type + "@" + role, credentials); | ||
} | ||
|
||
private VaultBootstrapConfig getConfig() { | ||
return vaultConfigHolder.getVaultBootstrapConfig(); | ||
} | ||
|
||
public Map<String, String> getDynamicCredentials(VaultDynamicCredentialsType type, String role) { | ||
String clientToken = vaultAuthManager.getClientToken(); | ||
VaultDynamicCredentials currentCredentials = getCachedCredentials(type, role); | ||
VaultDynamicCredentials credentials = getCredentials(currentCredentials, clientToken, type, role); | ||
putCachedCredentials(type, role, credentials); | ||
Map<String, String> properties = new HashMap<>(); | ||
properties.put(USER_PROPERTY_NAME, credentials.username); | ||
properties.put(PASSWORD_PROPERTY_NAME, credentials.password); | ||
properties.put(EXPIRATION_TIMESTAMP_PROPERTY_NAME, credentials.getExpireInstant().toString()); | ||
return properties; | ||
} | ||
|
||
public VaultDynamicCredentials getCredentials(VaultDynamicCredentials currentCredentials, | ||
String clientToken, | ||
VaultDynamicCredentialsType type, | ||
String role) { | ||
|
||
VaultDynamicCredentials credentials = currentCredentials; | ||
|
||
// check lease is still valid | ||
if (credentials != null) { | ||
credentials = validate(credentials, clientToken); | ||
} | ||
|
||
// extend lease if necessary | ||
if (credentials != null && credentials.shouldExtend(getConfig().renewGracePeriod)) { | ||
credentials = extend(credentials, clientToken, type, role); | ||
} | ||
|
||
// create lease if necessary | ||
if (credentials == null || credentials.isExpired() | ||
|| credentials.expiresSoon(getConfig().renewGracePeriod)) { | ||
credentials = create(clientToken, type, role); | ||
} | ||
|
||
return credentials; | ||
} | ||
|
||
private VaultDynamicCredentials validate(VaultDynamicCredentials credentials, String clientToken) { | ||
try { | ||
vaultInternalSystemBackend.lookupLease(clientToken, credentials.leaseId); | ||
return credentials; | ||
} catch (VaultClientException e) { | ||
if (e.getStatus() == 400) { // bad request | ||
log.debug("lease " + credentials.leaseId + " has become invalid"); | ||
return null; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
} | ||
|
||
private VaultDynamicCredentials extend(VaultDynamicCredentials currentCredentials, String clientToken, | ||
VaultDynamicCredentialsType type, String role) { | ||
VaultRenewLease vaultRenewLease = vaultInternalSystemBackend.renewLease(clientToken, currentCredentials.leaseId); | ||
LeaseBase lease = new LeaseBase(vaultRenewLease.leaseId, vaultRenewLease.renewable, vaultRenewLease.leaseDurationSecs); | ||
VaultDynamicCredentials credentials = new VaultDynamicCredentials(lease, currentCredentials.username, | ||
currentCredentials.password); | ||
sanityCheck(credentials, type, role); | ||
log.debug("extended " + role + "(" + type.getDefaultName() + ") credentials:" | ||
+ credentials.getConfidentialInfo(getConfig().logConfidentialityLevel)); | ||
return credentials; | ||
} | ||
|
||
private VaultDynamicCredentials create(String clientToken, VaultDynamicCredentialsType type, String role) { | ||
io.quarkus.vault.runtime.client.dto.dynamic.VaultDynamicCredentials vaultDynamicCredentials = vaultInternalDynamicCredentialsSecretEngine | ||
.generateCredentials(clientToken, type.getDefaultName(), role); | ||
LeaseBase lease = new LeaseBase(vaultDynamicCredentials.leaseId, vaultDynamicCredentials.renewable, | ||
vaultDynamicCredentials.leaseDurationSecs); | ||
VaultDynamicCredentials credentials = new VaultDynamicCredentials(lease, | ||
vaultDynamicCredentials.data.username, | ||
vaultDynamicCredentials.data.password); | ||
log.debug("generated " + role + "(" + type.getDefaultName() + ") credentials:" | ||
+ credentials.getConfidentialInfo(getConfig().logConfidentialityLevel)); | ||
sanityCheck(credentials, type, role); | ||
return credentials; | ||
} | ||
|
||
private void sanityCheck(VaultDynamicCredentials credentials, VaultDynamicCredentialsType type, String role) { | ||
credentials.leaseDurationSanityCheck(role + " (" + type.getDefaultName() + ")", getConfig().renewGracePeriod); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
...ons/vault/runtime/src/main/java/io/quarkus/vault/runtime/VaultDynamicCredentialsType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package io.quarkus.vault.runtime; | ||
|
||
public enum VaultDynamicCredentialsType { | ||
DATABASE("database"), | ||
|
||
; | ||
|
||
private String mount; | ||
|
||
VaultDynamicCredentialsType(String mount) { | ||
this.mount = mount; | ||
} | ||
|
||
public String getDefaultName() { | ||
return mount; | ||
} | ||
} |
Oops, something went wrong.