Skip to content

Support custom Credential Providers #341

Open
@lispyclouds

Description

@lispyclouds

Is your feature request related to a problem? Please describe.
At our workplace, we are looking to use this lib to connect some of our Kafka instances to ingest data from deployments on GCP via PubSub. We use a custom timed authentication mechanism for GCP based on Hashicorp Vault and as far as we can see we cannot use a custom piece of code/plugin which would support this. As this is something quite critical and useful at my place and there are more ways of auth which people might use later, we have a proposal for this and are happy to implement and contribute if deemed useful.

Describe the solution you'd like
As this depends on com.google.api.gax which provides the interface com.google.api.gax.core.CredentialsProvider of which we can see the various kinds of uses in here, we propose the following:

  1. Add a new config public static final String GCP_CREDENTIALS_CLASS_CONFIG to this class. This would be the fully qualified name of the class which contains the custom implementation of the the CredentialsProvider.
  2. Add a clause to load the custom class here:
    if (!credentialsClass.isEmpty()) {
      return ConnectorCredentialsProvider.fromClass(credentialsClass);
    }
  3. Add a new method fromClass() to this class.
    public static ConnectorCredentialsProvider fromClass(String credentialsClass) {
      try {
        final Class<?> klass = Class.forName(credentialsClass);
        final var obj = klass.getDeclaredConstructor().newInstance();
    
        if (!(obj instanceof CredentialsProvider)) {
          throw new IllegalArgumentException("Supplied class %s is not a CredentialsProvider".formatted(credentialsClass));
        }
    
        return new ConnectorCredentialsProvider(() -> ((CredentialsProvider) obj).getCredentials());
      } catch (Exception e) {
        throw new RuntimeException("Error loading class: " + e);
      }
    }
  4. Implement the class for Hashicorp Vault:
    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.api.gax.core.CredentialsProvider;
    
    class HashicorpVaultCredentialsProvider implements CredentialsProvider {
      @Override
      public GoogleCredentials getCredentials() {
        // do the custom calls to get the token here
        final var token = "this is from Hashicorp Vault";
    
        return new GoogleCredentials(token);
      }
    }

We think that this should be generic enough for not only our use case but for others too. If there is interest, we are happy to also implement the Hashicorp Vault implementation in the contribution as that's something quite ubiquitous.

Caveats and questions:

  • This relies on the interface com.google.api.gax.core.CredentialsProvider which is a transitive dependency of the lib. We are not sure if that's something to be considered as a stable thing to expose to users or should a new interface be created?

Describe alternatives you've considered
None as this lib is something we use and would like to keep using with these added features!

Additional context
None as of now.

Hopefully this is useful and looking forward to collaborating!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions