googleapis / googleapis/managedkafka

GcpBearerAuthCredentialProvider: eager GoogleCredentials initialization breaks multi-cloud deployments

Open
#51 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
11
Forks
22
PR merge metrics
No merged PRs in 30d

Description

### Summary

`GcpBearerAuthCredentialProvider` eagerly initializes `GoogleCredentials` in its constructor, causing it to fail during classpath scanning even when not actively used. This breaks multi-cloud deployments where multiple auth providers coexist on the classpath.

### Root cause

**In `com.google.cloud.hosted.kafka.auth.GcpBearerAuthCredentialProvider`:**
- [Line 48](https://github.com/googleapis/managedkafka/blob/main/kafka-java-auth/src/main/java/com/google/cloud/hosted/kafka/auth/GcpBearerAuthCredentialProvider.java#L48) eagerly creates a `GoogleCredentials` instance in the constructor

**In `io.confluent.kafka.schemaregistry.client.security.bearerauth.BearerAuthCredentialProviderFactory`:**
- [Line 28](https://github.com/confluentinc/schema-registry/blob/d5702952492c7b344f7794c4c692ccfe35d6ed5e/client/src/main/java/io/confluent/kafka/schemaregistry/client/security/bearerauth/BearerAuthCredentialProviderFactory.java#L28) instantiates **all** `BearerAuthCredentialProvider` implementations found on the classpath during service discovery

This means `GoogleCredentials` is instantiated even when the provider isn't configured for use, causing failures if Google credentials aren't available on the default provider chain.

### Impact

This prevents multi-cloud deployments where:
- Multiple bearer auth providers (e.g., Confluent Cloud + Google Cloud) exist on the classpath
- The application needs to dynamically choose which provider to use based on runtime configuration
- Google credentials may not be available in all environments

**Real-world example:** Our product [Kpow](https://factorhouse.io/kpow) provides first-class support for Google Managed Service for Apache Kafka (see [docs](https://docs.factorhouse.io/kpow/provider/google-msak)). Until this is fixed, we'll need to maintain a separate GCP-specific build, creating unnecessary friction for our customers using Google's managed services.

### Steps to reproduce

1. Add the`com.google.cloud.hosted.kafka/managed-kafka-auth-login-handler` dependency to your classpath alongside the `io.confluent/kafka-avro-serializer` dependency
2. Configure your SerDes instance (eg `io.confluent.kafka.serializers.KafkaAvroDeserializer` or similar) to use a non-Google provider - eg specifying `bearer.auth.credentials.source=CUSTOM | OAUTHBEARER | etc`
4. Deploy to an environment without Google Cloud credentials configured
5. Observe a runtime exception constructing the SerDes class:

```
java.util.ServiceConfigurationError: io.confluent.kafka.schemaregistry-client.security-bearerauth.BearerAuthCredentialProvider: Provider com-google.cloud.hosted.kafka.auth.GcpBearerAuthCredentialProvider...

Caused by: java.io.IOException: Your default credentials were not found. To set up Application Default Credentials for your environment, see https://cloud.google.com/docs/authentication/external/set-up-adc.
```

### Expected behavior

The provider should only attempt to initialize credentials when explicitly configured and used.

### Proposed solution

Defer `GoogleCredentials` initialization from the constructor to the `configure(Map configs)` method, which is called only when Confluent's Schema Registry library has positively identified this provider based on configuration.

**Considerations:**
- The overloaded constructor for injecting custom credentials (used in testing) may need adjustment
- Custom credentials could potentially be passed via the configuration map instead
- This change would align with the lazy initialization pattern used by other auth providers

### Workaround

Currently, users must either:
- Ensure Google credentials are always available, even when unused
- Maintain separate builds with different auth providers

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.