feat(gcp-auth-extension): Support custom credentials via configuration properties#2767
feat(gcp-auth-extension): Support custom credentials via configuration properties#2767keshavdandeva wants to merge 7 commits intoopen-telemetry:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds support for supplying Google Cloud credentials via configuration (file path or inline JSON) for the GCP auth extension, with tests covering the new resolution behavior.
Changes:
- Add new configuration options for credentials file path and inline JSON.
- Resolve credentials from config properties before falling back to Application Default Credentials.
- Add unit tests validating credential loading and fallback behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| gcp-auth-extension/src/main/java/io/opentelemetry/contrib/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java | Adds credential resolution from config properties (file/JSON) with ADC fallback. |
| gcp-auth-extension/src/main/java/io/opentelemetry/contrib/gcp/auth/ConfigurableOption.java | Introduces new configurable options for credentials path and JSON. |
| gcp-auth-extension/src/test/java/io/opentelemetry/contrib/gcp/auth/GcpAuthAutoConfigurationCustomizerProviderTest.java | Adds tests for credentials loading from file path/JSON and ADC fallback. |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds configuration-driven credential loading to gcp-auth-extension, allowing users to supply Google Cloud credentials via file path or raw JSON while preserving ADC fallback behavior.
Changes:
- Added new configuration options for credentials path and credentials JSON.
- Implemented lazy, prioritized credential resolution (path → JSON → ADC) with caching.
- Added unit tests covering custom credential sources and fallback behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| gcp-auth-extension/src/main/java/io/opentelemetry/contrib/gcp/auth/ConfigurableOption.java | Adds new configuration enum entries for credentials path/JSON. |
| gcp-auth-extension/src/main/java/io/opentelemetry/contrib/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java | Adds lazy credential resolution with a small cache and a defined precedence chain. |
| gcp-auth-extension/src/test/java/io/opentelemetry/contrib/gcp/auth/GcpAuthAutoConfigurationCustomizerProviderTest.java | Adds tests for credentials loading from path/JSON and ADC fallback. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@keshavdandeva are you able to sign the CLA? |
Yes, done |
| * `google.cloud.credentials.json`. | ||
| */ | ||
| GOOGLE_CLOUD_CREDENTIALS_JSON("Google Cloud Credentials JSON String"); | ||
|
|
There was a problem hiding this comment.
To improve clarity, the documentation should indicate if the path should be relative or absolute.
Current documentation comments simply state - "Represents the Google Cloud Credentials Path option", but does not explain what these options are.
|
|
||
| private static final Logger logger = | ||
| Logger.getLogger(GcpAuthAutoConfigurationCustomizerProvider.class.getName()); | ||
| private static final Map<ConfigProperties, GoogleCredentials> credentialsCache = |
There was a problem hiding this comment.
Does this need to be a map? The map implicates that there could be multiple GoogleCredentials object for authenticating to the same backend.
IIUC, the same configProperties are used, so the Map will only ever have a single entry.
There was a problem hiding this comment.
You are correct that within a single auto-configuration pass, the same ConfigProperties instance is shared, so the map will indeed only have a single entry.
I used a map (specifically a WeakHashMap) to defensively support scenarios where multiple SDK instances might be created in the same JVM or sequential unit tests with different configurations, ensuring they don't conflict.
However, if you disagree and prefer to simplify it to a single cached instance, I am happy to change it back
| } | ||
| } | ||
|
|
||
| private static GoogleCredentials loadCredentials(ConfigProperties props) { |
There was a problem hiding this comment.
Nit: Rename props to configProperties to maintain consistency.
| ConfigurableOption.GOOGLE_CLOUD_CREDENTIALS_PATH.getConfiguredValueAsOptional(props); | ||
| if (credsPath.isPresent()) { | ||
| try (FileInputStream fis = new FileInputStream(credsPath.get())) { | ||
| return GoogleCredentials.fromStream(fis); |
There was a problem hiding this comment.
This method is marked as obsolete citing potential security risk.
There was a problem hiding this comment.
Thanks for the pointer. I have removed the use of GoogleCredentials.fromStream and switched to ServiceAccountCredentials.fromStream for now, as service accounts might be fine for our use case.
However, I'm wondering how we should ideally support other credential types (like external accounts or user credentials) in the future without re-implementing the auto-detection logic of the obsolete method. Do you have a recommendation on whether we should stick to Service Accounts for these properties, or if we should implement a custom detector to route to other specific load methods?
| new ByteArrayInputStream(credsJson.get().getBytes(StandardCharsets.UTF_8))) { | ||
| return GoogleCredentials.fromStream(bais); | ||
| } catch (IOException e) { | ||
| throw new ConfigurationException("Failed to load credentials from JSON string", e); |
There was a problem hiding this comment.
Since this error would be generated from the line GoogleCredentials.fromStream - I would think to wrap this and throw a GoogleAuthException instead.
You can add a new Reason: FAILED_CREDENTIAL_CREATION and then re-use it in above case as well.
| try (FileInputStream fis = new FileInputStream(credsPath.get())) { | ||
| return GoogleCredentials.fromStream(fis); | ||
| } catch (IOException e) { | ||
| throw new ConfigurationException( | ||
| "Failed to load credentials from file: " + new File(credsPath.get()).getName(), e); | ||
| } |
There was a problem hiding this comment.
This handling should distinguish between 2 different scenarios:
credsPathis invalid/wrong:ConfigurationException.- Unable to create
GoogleCredentialsfrom a validcredsPath:GoogleAuthException.
|
|
||
| @Test | ||
| void testCredentialsLoadedFromFilePath() throws IOException { | ||
| File tempFile = File.createTempFile("gcp-creds", ".json"); |
There was a problem hiding this comment.
WDYT about adding a dummy creds file in test/resources.
The file could contain valid looking fields to see if GoogleCredentials can be actually parsed from it.
There was a problem hiding this comment.
I looked into adding a dummy file, but generating a valid private key structure without real keys proved to be complicated and prone to JSON parsing issues. I think the existing unit tests with mocks are sufficient to verify the logic, but I can try to add it if you insist.
There was a problem hiding this comment.
There could also be tests that exercise the case where either the file (JSON/Creds) is not found or the content in the file is malformed/invalid.
feat(gcp-auth-extension): Support custom credentials via configuration properties
Description
Currently,
gcp-auth-extensionis hardcoded to use Application Default Credentials (ADC). This PR adds support for specifying custom Service Account credentials via configuration properties (file path or JSON string), while maintaining backward compatibility by falling back to ADC.Key Changes
gcp-auth-extensiongoogle.cloud.credentials.pathandgoogle.cloud.credentials.jsonoptions inConfigurableOption.java.ConfigPropertiesinstance inGcpAuthAutoConfigurationCustomizerProvider.javato avoid redundant I/O.ServiceAccountCredentials.fromStreaminstead of the obsolete genericGoogleCredentials.fromStreamto address security concerns.ConfigurationException) and a failure to create credentials (GoogleAuthException).Verification Results
./gradlew :gcp-auth-extension:test-> BUILD SUCCESSFUL