All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.vault.runtime.VaultDbManager Maven / Gradle / Ivy

package io.quarkus.vault.runtime;

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.database.VaultDatabaseCredentials;
import io.quarkus.vault.runtime.client.dto.sys.VaultRenewLease;
import io.quarkus.vault.runtime.client.secretengine.VaultInternalDatabaseSecretEngine;
import io.quarkus.vault.runtime.config.VaultBootstrapConfig;

@Singleton
public class VaultDbManager {

    private static final Logger log = Logger.getLogger(VaultDbManager.class.getName());

    ConcurrentHashMap credentialsCache = new ConcurrentHashMap<>();
    private VaultAuthManager vaultAuthManager;
    private VaultConfigHolder vaultConfigHolder;
    private VaultInternalSystemBackend vaultInternalSystemBackend;
    private VaultInternalDatabaseSecretEngine vaultInternalDatabaseSecretEngine;

    public VaultDbManager(VaultConfigHolder vaultConfigHolder, VaultAuthManager vaultAuthManager,
            VaultInternalSystemBackend vaultInternalSystemBackend,
            VaultInternalDatabaseSecretEngine vaultInternalDatabaseSecretEngine) {
        this.vaultConfigHolder = vaultConfigHolder;
        this.vaultAuthManager = vaultAuthManager;
        this.vaultInternalSystemBackend = vaultInternalSystemBackend;
        this.vaultInternalDatabaseSecretEngine = vaultInternalDatabaseSecretEngine;
    }

    private VaultBootstrapConfig getConfig() {
        return vaultConfigHolder.getVaultBootstrapConfig();
    }

    public Map getDynamicDbCredentials(String databaseCredentialsRole) {
        String clientToken = vaultAuthManager.getClientToken();
        VaultDynamicDatabaseCredentials currentCredentials = credentialsCache.get(databaseCredentialsRole);
        VaultDynamicDatabaseCredentials credentials = getCredentials(currentCredentials, clientToken, databaseCredentialsRole);
        credentialsCache.put(databaseCredentialsRole, credentials);
        Map properties = new HashMap<>();
        properties.put(USER_PROPERTY_NAME, credentials.username);
        properties.put(PASSWORD_PROPERTY_NAME, credentials.password);
        return properties;
    }

    public VaultDynamicDatabaseCredentials getCredentials(VaultDynamicDatabaseCredentials currentCredentials,
            String clientToken,
            String databaseCredentialsRole) {

        VaultDynamicDatabaseCredentials 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, databaseCredentialsRole);
        }

        // create lease if necessary
        if (credentials == null || credentials.isExpired()
                || credentials.expiresSoon(getConfig().renewGracePeriod)) {
            credentials = create(clientToken, databaseCredentialsRole);
        }

        return credentials;
    }

    private VaultDynamicDatabaseCredentials validate(VaultDynamicDatabaseCredentials 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 VaultDynamicDatabaseCredentials extend(VaultDynamicDatabaseCredentials currentCredentials, String clientToken,
            String databaseCredentialsRole) {
        VaultRenewLease vaultRenewLease = vaultInternalSystemBackend.renewLease(clientToken, currentCredentials.leaseId);
        LeaseBase lease = new LeaseBase(vaultRenewLease.leaseId, vaultRenewLease.renewable, vaultRenewLease.leaseDurationSecs);
        VaultDynamicDatabaseCredentials credentials = new VaultDynamicDatabaseCredentials(lease, currentCredentials.username,
                currentCredentials.password);
        sanityCheck(credentials, databaseCredentialsRole);
        log.debug("extended " + databaseCredentialsRole + " credentials with: "
                + credentials.getConfidentialInfo(getConfig().logConfidentialityLevel));
        return credentials;
    }

    private VaultDynamicDatabaseCredentials create(String clientToken, String databaseCredentialsRole) {
        VaultDatabaseCredentials vaultDatabaseCredentials = vaultInternalDatabaseSecretEngine.generateCredentials(clientToken,
                databaseCredentialsRole);
        LeaseBase lease = new LeaseBase(vaultDatabaseCredentials.leaseId, vaultDatabaseCredentials.renewable,
                vaultDatabaseCredentials.leaseDurationSecs);
        VaultDynamicDatabaseCredentials credentials = new VaultDynamicDatabaseCredentials(lease,
                vaultDatabaseCredentials.data.username,
                vaultDatabaseCredentials.data.password);
        log.debug("generated " + databaseCredentialsRole + " credentials: "
                + credentials.getConfidentialInfo(getConfig().logConfidentialityLevel));
        sanityCheck(credentials, databaseCredentialsRole);
        return credentials;
    }

    private void sanityCheck(VaultDynamicDatabaseCredentials credentials, String databaseCredentialsRole) {
        credentials.leaseDurationSanityCheck(databaseCredentialsRole, getConfig().renewGracePeriod);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy