Skip to content

feat: add Application Default Credentials (ADC) support#125

Merged
jpoehnelt merged 2 commits intogoogleworkspace:mainfrom
zerone0x:fix/adc-support-103
Mar 5, 2026
Merged

feat: add Application Default Credentials (ADC) support#125
jpoehnelt merged 2 commits intogoogleworkspace:mainfrom
zerone0x:fix/adc-support-103

Conversation

@zerone0x
Copy link
Contributor

@zerone0x zerone0x commented Mar 5, 2026

Description

Closes #103

Adds Application Default Credentials (ADC) as a 4th credential source in get_token().

New credential lookup order

Priority Source
0 GOOGLE_WORKSPACE_CLI_TOKEN env var (raw token)
1 GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE env var
2 Encrypted credentials (~/.config/gws/credentials.enc)
3 Plaintext credentials (~/.config/gws/credentials.json)
4 ADC — GOOGLE_APPLICATION_CREDENTIALS env var, then ~/.config/gcloud/application_default_credentials.json

Supported ADC flows

This unlocks two common setups:

  1. User OAuth via gcloud ADC (recommended for personal accounts):

    gcloud auth application-default login --client-id-file=client_secret.json
    # No need to run `gws auth login` separately
  2. Service account via GOOGLE_APPLICATION_CREDENTIALS:

    export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
    gws drive files list

Both authorized_user and service_account ADC formats are detected automatically via the type field.

As noted in the issue, most Workspace APIs require scopes granted to a specific user OAuth client, so service account ADC coverage is limited to APIs that support domain-wide delegation. User OAuth ADC with a custom client (via --client-id-file) works for all standard Workspace APIs.

Dry Run Output:

// Not applicable — credential loading logic change, no HTTP request generated

Checklist:

  • My code follows the AGENTS.md guidelines (no generated google-* crates).
  • I have run cargo fmt --all to format the code perfectly. (no Rust toolchain on build host — CI will verify)
  • I have run cargo clippy -- -D warnings and resolved all warnings. (CI will verify)
  • I have added tests that prove my fix is effective or that my feature works. (test_load_credentials_adc_env_var_authorized_user, test_load_credentials_adc_env_var_missing_file)
  • I have provided a Changeset file to document my changes.

🤖 Generated with Claude Code

@zerone0x zerone0x requested a review from jpoehnelt as a code owner March 5, 2026 06:19
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: 0739dd5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@gemini-code-assist
Copy link
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@google-cla
Copy link

google-cla bot commented Mar 5, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

…ace#103)

Extends the credential chain in get_token() to include ADC as a 4th source:
  1. GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE env var
  2. Encrypted credentials (~/.config/gws/credentials.enc)
  3. Plaintext credentials (~/.config/gws/credentials.json)
  4. ADC — GOOGLE_APPLICATION_CREDENTIALS env var, then
     ~/.config/gcloud/application_default_credentials.json

Both authorized_user and service_account ADC formats are detected via the
'type' field and parsed accordingly.  This means users can authenticate with:
  gcloud auth application-default login --client-id-file=client_secret.json

and gws will automatically pick up those credentials.

Closes googleworkspace#103

Co-Authored-By: Claude <noreply@anthropic.com>
@zerone0x zerone0x force-pushed the fix/adc-support-103 branch from 19e4138 to 511dba8 Compare March 5, 2026 06:57
@jpoehnelt
Copy link
Member

/gemini review

@codecov
Copy link

codecov bot commented Mar 5, 2026

Codecov Report

❌ Patch coverage is 95.68966% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.46%. Comparing base (7fa8bda) to head (0739dd5).
⚠️ Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
src/auth.rs 95.68% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #125      +/-   ##
==========================================
+ Coverage   54.88%   55.46%   +0.57%     
==========================================
  Files          38       38              
  Lines       13085    13254     +169     
==========================================
+ Hits         7182     7351     +169     
  Misses       5903     5903              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@jpoehnelt jpoehnelt left a comment

Choose a reason for hiding this comment

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

duplicated credential-parsing logic that should be extracted, missing service_account ADC test, incorrect well-known path on macOS (dirs::config_dir vs ~/.config/gcloud), silent fallthrough when GOOGLE_APPLICATION_CREDENTIALS points to missing file, incomplete changeset priority list, and a note on unsafe env var usage in tests.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for Application Default Credentials (ADC). While the implementation is generally robust, a significant logic flaw was identified: the application may silently fall back to ADC even when a specific account is requested via the --account flag. This can lead to actions being performed by the wrong identity and incorrect token caching. Additionally, consider improvements for documentation consistency in the changeset file, a minor performance optimization in JSON parsing, and the removal of unnecessary unsafe blocks in tests.

- Extract duplicated JSON credential parsing into parse_credential_file()
  helper to reduce duplication between GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE
  and ADC code paths; uses serde_json::from_value to avoid second string parse
- Fix well-known ADC path on macOS: dirs::config_dir() returns
  ~/Library/Application Support on macOS, not ~/.config; use
  dirs::home_dir().join('.config/gcloud/...') instead
- Hard-error when GOOGLE_APPLICATION_CREDENTIALS points to a missing file
  (was: silently fall through to 'No credentials found')
- Add test_load_credentials_adc_env_var_service_account covering service
  account credentials loaded via GOOGLE_APPLICATION_CREDENTIALS
- Remove unnecessary unsafe blocks from env var tests (set_var/remove_var
  are not unsafe functions; thread safety is already handled by serial_test)
- Update changeset to include GOOGLE_WORKSPACE_CLI_TOKEN at top of lookup
  order and clarify ADC fallback behaviour

Addresses review feedback from jpoehnelt on googleworkspace#125.

Co-Authored-By: Claude <noreply@anthropic.com>
@zerone0x
Copy link
Contributor Author

zerone0x commented Mar 5, 2026

good catches, updated:

  • extracted the JSON parsing into a helper (parse_credential_file) so the env file and ADC paths share the same logic, also switched to from_value to skip the second string parse
  • fixed the macOS path — dirs::config_dir() gives ~/Library/Application Support on mac which is wrong, now using home_dir().join(".config/gcloud/...")
  • GOOGLE_APPLICATION_CREDENTIALS pointing to a missing file now hard-errors instead of silently falling through
  • added the missing service_account test for ADC
  • removed the unsafe blocks, they were misleading
  • updated the changeset to include GOOGLE_WORKSPACE_CLI_TOKEN at the top

@jpoehnelt
Copy link
Member

Re: the Gemini review concern about --account silently falling through to ADC — after tracing the code, this is a false positive. resolve_account() already hard-errors when an explicit --account is passed and the account isn't in the registry (both the (Some, Some) and (Some, None) arms bail). ADC is only reachable via the (None, None) path — no --account flag, no registry, no legacy creds — which is exactly the "fresh install with only gcloud configured" scenario where ADC should kick in.

@jpoehnelt
Copy link
Member

Re: the Gemini review concern about --account silently falling through to ADC — this is a false positive. resolve_account() already hard-errors when an explicit --account is passed and the account isn't in the registry (both the (Some, Some) and (Some, None) arms bail). ADC is only reachable via the (None, None) path — no --account flag, no registry, no legacy creds — which is the fresh-install-with-gcloud scenario where ADC should kick in.

1 similar comment
@jpoehnelt
Copy link
Member

Re: the Gemini review concern about --account silently falling through to ADC — this is a false positive. resolve_account() already hard-errors when an explicit --account is passed and the account isn't in the registry (both the (Some, Some) and (Some, None) arms bail). ADC is only reachable via the (None, None) path — no --account flag, no registry, no legacy creds — which is the fresh-install-with-gcloud scenario where ADC should kick in.

@jpoehnelt jpoehnelt merged commit b38b760 into googleworkspace:main Mar 5, 2026
23 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support ADC

2 participants