How to do fine-grained Credentials caching in a Credentials Provider?

25 views
Skip to first unread message

Chris Kilding

unread,
May 10, 2019, 10:19:04 AM5/10/19
to jenkin...@googlegroups.com

Hello, 


I need to implement fine-grained caching of non-secret credential metadata in my credentials provider plugin, but I’m not sure how to get the information I need to build this cache from the CredentialsProvider interface.


The official guide did not seem to have any suggestions for this: https://github.com/jenkinsci/credentials-plugin/blob/master/docs/implementation.adoc#implementing-a-new-credentialsprovider


It should be possible to do this neatly with a caching library like Guava Cache, but it appears that to make this work I must know the ID of a specific credential that Jenkins wants.


If I had that piece of information, I could write a Guava cache loader something like this:


private class CredentialsCacheLoader extends CacheLoader<String, StringCredentials> {

    private var secretsManager;


    @Override

    public StringCredentials load(String key) throws Exception {

        var secret = secretsManager.describeSecret(key);

        var creds = convertToCredentials(secret);

        return creds;

    }


    private static StringCredentials convertToCredentials(Secret secret) {

        // return some implementation of StringCredentials

    }

}


And construct a Guava cache something like this:


var secretsManager = AWSSecretsManagerClient.builder().build();

var cache = CacheBuilder.newBuilder()

        .expireAfterRead(5, TimeUnit.MINUTES)

        .maximumSize(1000)

        .build(new CredentialsCacheLoader(secretsManager));


And write a CredentialsProvider something like this:


public class AWSCredentialsProvider extends CredentialsProvider {

    private var cache;


    @Override

    public <C extends Credentials> List<C> getCredentials(Class<C> type, ItemGroup itemGroup, Authentication authentication) {

        // Here’s the problem - I need the ID of a secret to look up, but the signature doesn’t provide it.

        var id = ???

        var credential = cache.getIfPresent(id);

        return ???

    }

}


Unfortunately, as we can see above, the method signature that CredentialsProvider provides only indicates the type of credentials to look up.


So it appears the best I can do is to fetch the entire list of secrets from the remote provider at the time, construct proxy objects for them, and keep a coarse-grained cache of the whole lot (with something like Suppliers.memoizeWithExpiration).


This doesn’t seem right - other remote Jenkins credentials providers exist, and they must have faced this problem before. Am I missing something?


Thanks in advance,


Chris


Reply all
Reply to author
Forward
0 new messages