Skip to content

feat(gcp-auth-extension): Support custom credentials via configuration properties#2767

Open
keshavdandeva wants to merge 7 commits intoopen-telemetry:mainfrom
keshavdandeva:kd/gcp-auth-extension
Open

feat(gcp-auth-extension): Support custom credentials via configuration properties#2767
keshavdandeva wants to merge 7 commits intoopen-telemetry:mainfrom
keshavdandeva:kd/gcp-auth-extension

Conversation

@keshavdandeva
Copy link
Copy Markdown

@keshavdandeva keshavdandeva commented Apr 17, 2026

feat(gcp-auth-extension): Support custom credentials via configuration properties

Description

Currently, gcp-auth-extension is 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-extension

  • New Properties: Added google.cloud.credentials.path and google.cloud.credentials.json options in ConfigurableOption.java.
  • Lazy & Cached Resolution: Moved credentials resolution to be lazy and cached per ConfigProperties instance in GcpAuthAutoConfigurationCustomizerProvider.java to avoid redundant I/O.
  • Type-Safe Loading: Uses ServiceAccountCredentials.fromStream instead of the obsolete generic GoogleCredentials.fromStream to address security concerns.
  • Improved Error Handling: Distinguishes between a missing file (ConfigurationException) and a failure to create credentials (GoogleAuthException).
  • Tests: Added unit tests for file path, JSON string, precedence rules, missing files, and malformed JSON.
  • Docs: Updated Javadoc to clarify that both relative and absolute paths are supported, and to reflect the new capabilities.

Verification Results

  • Executed unit tests: ./gradlew :gcp-auth-extension:test -> BUILD SUCCESSFUL

Copilot AI review requested due to automatic review settings April 17, 2026 15:32
@keshavdandeva keshavdandeva requested a review from a team as a code owner April 17, 2026 15:32
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented Apr 17, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

@github-actions github-actions Bot requested review from jsuereth and psx95 April 17, 2026 15:35
@keshavdandeva keshavdandeva marked this pull request as draft April 17, 2026 15:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@keshavdandeva keshavdandeva requested a review from Copilot April 17, 2026 15:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 keshavdandeva marked this pull request as ready for review April 20, 2026 12:46
@jaydeluca
Copy link
Copy Markdown
Member

@keshavdandeva are you able to sign the CLA?

@keshavdandeva
Copy link
Copy Markdown
Author

@keshavdandeva are you able to sign the CLA?

Yes, done

* `google.cloud.credentials.json`.
*/
GOOGLE_CLOUD_CREDENTIALS_JSON("Google Cloud Credentials JSON String");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the comments


private static final Logger logger =
Logger.getLogger(GcpAuthAutoConfigurationCustomizerProvider.class.getName());
private static final Map<ConfigProperties, GoogleCredentials> credentialsCache =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Rename props to configProperties to maintain consistency.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

ConfigurableOption.GOOGLE_CLOUD_CREDENTIALS_PATH.getConfiguredValueAsOptional(props);
if (credsPath.isPresent()) {
try (FileInputStream fis = new FileInputStream(credsPath.get())) {
return GoogleCredentials.fromStream(fis);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is marked as obsolete citing potential security risk.

See google-auth-library-java.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +142 to +147
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);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handling should distinguish between 2 different scenarios:

  1. credsPath is invalid/wrong: ConfigurationException.
  2. Unable to create GoogleCredentials from a valid credsPath: GoogleAuthException.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


@Test
void testCredentialsLoadedFromFilePath() throws IOException {
File tempFile = File.createTempFile("gcp-creds", ".json");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@keshavdandeva keshavdandeva requested a review from psx95 May 7, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants