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