Skip to content

Conversation

@chenjian2664
Copy link
Contributor

@chenjian2664 chenjian2664 commented Oct 27, 2025

Add a dedicated NO_CREDENTIALS type to explicitly support unauthenticated access.

Description

Fixes #26984

Additional context and related issues

Release notes

( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
(x) Release notes are required, with the following suggested text:

## Section
* Add `NO_CREDENTIALS` authentication type for GCS. ({issue}`26984`)

@cla-bot cla-bot bot added the cla-signed label Oct 27, 2025
@sourcery-ai
Copy link

sourcery-ai bot commented Oct 27, 2025

Reviewer's Guide

This PR explicitly adds a NO_CREDENTIALS authentication mode for GCS by splitting service-account logic from unauthenticated access, refactors credential handling in the service account implementation, tightens configuration validation for different auth types, and updates tests and documentation accordingly.

Class diagram for new and updated GCS authentication classes

classDiagram
    class GcsAuth {
        <<interface>>
        +setAuth(StorageOptions.Builder builder, ConnectorIdentity identity)
    }
    class GcsServiceAccountAuth {
        -GoogleCredentials jsonGoogleCredential
        +GcsServiceAccountAuth(GcsFileSystemConfig config)
        +setAuth(StorageOptions.Builder builder, ConnectorIdentity identity)
    }
    class NoCredentialsAuth {
        +setAuth(StorageOptions.Builder builder, ConnectorIdentity identity)
    }
    GcsServiceAccountAuth --|> GcsAuth
    NoCredentialsAuth --|> GcsAuth
Loading

Class diagram for updated GcsFileSystemConfig AuthType enum and validation

classDiagram
    class GcsFileSystemConfig {
        +AuthType : enum (ACCESS_TOKEN, SERVICE_ACCOUNT, NO_CREDENTIALS)
        +isServiceAccountAuthValid() : boolean
        +isNonServiceAccountAuthValid() : boolean
    }
Loading

File-Level Changes

Change Details Files
Introduce NO_CREDENTIALS auth type
  • Add NO_CREDENTIALS to AuthType enum
  • Implement NoCredentialsAuth to use default or no credentials
  • Bind NO_CREDENTIALS to NoCredentialsAuth in DI
  • Document new auth type in Sphinx docs
GcsFileSystemConfig.java
NoCredentialsAuth.java
GcsFileSystemModule.java
file-system-gcs.md
Refactor service-account credential handling
  • Replace Optional with mandatory GoogleCredentials field
  • Use checkArgument to enforce exactly one key source
  • Simplify setAuth to always call builder.setCredentials
GcsServiceAccountAuth.java
Split and tighten config validation for auth types
  • Replace single isAuthMethodValid with service vs non-service AssertTrue methods
  • Enforce mutual exclusivity of json key/ file for SERVICE_ACCOUNT
  • Prevent json-key usage for non-service auth and use-access-token conflicts
GcsFileSystemConfig.java
Extend and adjust tests for new auth flows
  • Add validation failure cases for NO_CREDENTIALS in TestGcsFileSystemConfig
  • Update TestGcsStorageFactory to use NoCredentialsAuth
TestGcsFileSystemConfig.java
TestGcsStorageFactory.java

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions bot added the docs label Oct 27, 2025
@chenjian2664 chenjian2664 force-pushed the gcs-no-credentials-auth branch from f1cee33 to 3e7dc29 Compare October 27, 2025 01:10
@ebyhr
Copy link
Member

ebyhr commented Oct 27, 2025

@chenjian2664 Is this a release blocker of 478?

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The documentation refers to NO_CREDENTIALS_AUTH but the enum value is NO_CREDENTIALS—please align the docs with the actual enum name.
  • Add a unit test for NoCredentialsAuth to verify that it falls back to NoCredentials when ADC lookup throws an IOException.
  • The GcsFileSystemConfig validation tests have a lot of repetitive assertFailsValidation calls—consider parameterizing these cases to reduce duplication.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The documentation refers to `NO_CREDENTIALS_AUTH` but the enum value is `NO_CREDENTIALS`—please align the docs with the actual enum name.
- Add a unit test for NoCredentialsAuth to verify that it falls back to NoCredentials when ADC lookup throws an IOException.
- The GcsFileSystemConfig validation tests have a lot of repetitive assertFailsValidation calls—consider parameterizing these cases to reduce duplication.

## Individual Comments

### Comment 1
<location> `lib/trino-filesystem-gcs/src/test/java/io/trino/filesystem/gcs/TestGcsFileSystemConfig.java:136-142` </location>
<code_context>
         assertFailsValidation(
                 new GcsFileSystemConfig()
                         .setAuthType(AuthType.ACCESS_TOKEN)
-                        .setJsonKey("{}}"),
-                "authMethodValid",
-                "Either gcs.auth-type or gcs.json-key or gcs.json-key-file-path must be set",
+                        .setJsonKey("{}"),
+                "nonServiceAuthValid",
+                "Can't set gcs.json-key or gcs.json-key-file-path",
+                AssertTrue.class);
+
+        assertFailsValidation(
</code_context>

<issue_to_address>
**suggestion (testing):** Good coverage of validation for NO_CREDENTIALS, but missing positive test cases.

Please add tests that verify valid NO_CREDENTIALS configurations to ensure positive scenarios are covered.
</issue_to_address>

### Comment 2
<location> `lib/trino-filesystem-gcs/src/test/java/io/trino/filesystem/gcs/TestGcsStorageFactory.java:35-37` </location>
<code_context>
         GcsFileSystemConfig config = new GcsFileSystemConfig();

-        GcsStorageFactory storageFactory = new GcsStorageFactory(config, new GcsServiceAccountAuth(config));
+        GcsStorageFactory storageFactory = new GcsStorageFactory(config, new NoCredentialsAuth());

         Credentials actualCredentials;
         try (Storage storage = storageFactory.create(ConnectorIdentity.ofUser("test"))) {
</code_context>

<issue_to_address>
**suggestion (testing):** Test for NoCredentialsAuth only covers default config; edge cases are missing.

Add tests for cases where application default credentials are unavailable to confirm NoCredentialsAuth correctly acts as a fallback.

Suggested implementation:

```java
        // No credentials options are set
        GcsFileSystemConfig config = new GcsFileSystemConfig();

        GcsStorageFactory storageFactory = new GcsStorageFactory(config, new NoCredentialsAuth());

        Credentials actualCredentials;
        try (Storage storage = storageFactory.create(ConnectorIdentity.ofUser("test"))) {

        }

        @Test
        public void testNoCredentialsAuthFallbackWhenNoADC() throws Exception
        {
            // Simulate environment with no ADC
            String originalGoogleApplicationCredentials = System.getenv("GOOGLE_APPLICATION_CREDENTIALS");
            try {
                // Unset the ADC environment variable
                if (originalGoogleApplicationCredentials != null) {
                    System.clearProperty("GOOGLE_APPLICATION_CREDENTIALS");
                }

                GcsFileSystemConfig config = new GcsFileSystemConfig();
                GcsStorageFactory storageFactory = new GcsStorageFactory(config, new NoCredentialsAuth());

                try (Storage storage = storageFactory.create(ConnectorIdentity.ofUser("test"))) {
                    Credentials credentials = storage.getOptions().getCredentials();
                    // Should be null or a NoCredentials instance, depending on implementation
                    assertTrue(credentials == null || credentials.getClass().getSimpleName().equals("NoCredentials"), "NoCredentialsAuth should fallback to no credentials");
                }
            }
            finally {
                // Restore ADC environment variable
                if (originalGoogleApplicationCredentials != null) {
                    System.setProperty("GOOGLE_APPLICATION_CREDENTIALS", originalGoogleApplicationCredentials);
                }
            }
        }

```

- If your codebase uses a different way to unset or mock environment variables, adjust the test setup accordingly.
- If `NoCredentialsAuth` produces a specific credentials type, update the assertion to check for that type.
- Ensure the test method is annotated with `@Test` and imported from your test framework (e.g., JUnit).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@chenjian2664 chenjian2664 force-pushed the gcs-no-credentials-auth branch 2 times, most recently from 0e0a502 to 1c8d57a Compare October 27, 2025 01:38
@ebyhr
Copy link
Member

ebyhr commented Oct 27, 2025

CI failure is related to this change:

Error:  io.trino.filesystem.gcs.TestGcsStorageFactory.testDefaultCredentials -- Time elapsed: 0.609 s <<< FAILURE!
org.opentest4j.AssertionFailedError: 
[if credentials are not explicitly configured, should have same behavior as the GCS client] 
expected: null
 but was: NoCredentials{requestMetadata=null, temporaryAccess=null}
	at io.trino.filesystem.gcs.TestGcsStorageFactory.testDefaultCredentials(TestGcsStorageFactory.java:44)

@chenjian2664 chenjian2664 force-pushed the gcs-no-credentials-auth branch from 1c8d57a to eeee061 Compare October 27, 2025 05:44
@ebyhr
Copy link
Member

ebyhr commented Oct 27, 2025

Add NO_CREDENTIALS_AUTH authentication type for GCS

Please replace NO_CREDENTIALS_AUTH with NO_CREDENTIALS in the commit title.

@chenjian2664 chenjian2664 force-pushed the gcs-no-credentials-auth branch from eeee061 to f91c5bb Compare October 27, 2025 07:04
Comment on lines 81 to 83
* `NO_CREDENTIALS`: allows accessing Google Cloud Storage without providing
explicit credentials. Attempts to acquire application default credentials from the
environment, and falls back to no-credentials access if none are available.
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be behaviour by default ? Why do we need to implement them as a dedicated enum or configure them out ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously, the NO_CREDENTIALS behavior was implicitly covered by the SERVICE_ACCOUNT auth type, but in practice it was never reachable because the SERVICE_ACCOUNT validator requires either a json-key or json-key-file-path to be configured. By introducing a dedicated NO_CREDENTIALS type, we can now support this scenario explicitly and ensure the validation logic stays consistent, context see #26984

Copy link
Member

Choose a reason for hiding this comment

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

I meant if we didn't set the auth type to any value - it should exhibit this behaviour right ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously the default is SERVICE_ACCOUNT, so I don't want to change it in this pr - just want to introduce a new type.
WDYT @wendigo

@chenjian2664 chenjian2664 force-pushed the gcs-no-credentials-auth branch from 5a088ac to afe4615 Compare October 30, 2025 07:44
Comment on lines -64 to -65
// This is consistent with the GCP SDK when no credentials are available in the environment
return null;
Copy link

Choose a reason for hiding this comment

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

I'd leave it as-is now.

@chenjian2664 chenjian2664 force-pushed the gcs-no-credentials-auth branch from 58dc340 to 390f406 Compare October 30, 2025 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

Enhance 'unauthenticated' auth type for GCS storage

5 participants