Skip to content

Conversation

@nazq
Copy link
Contributor

@nazq nazq commented Nov 6, 2025

Summary

Adds support for external_account_authorized_user credentials used by Google Cloud Workforce Identity Federation. This credential type is created when users authenticate with gcloud auth application-default login using workforce identity pools with external identity providers.

Problem

Previously, object_store only supported two Application Default Credential types:

  • service_account
  • authorized_user

Users with Workforce Identity Federation encountered deserialization errors when their ADC file contained external_account_authorized_user credentials, preventing them from using the library even though they had valid Google Cloud authentication.

This affected enterprise environments where organizations use external identity providers (like Azure AD, Okta, etc.) to authenticate users to Google Cloud resources.

Solution

This PR extends credential support to include the external_account_authorized_user type:

  1. New credential struct with OAuth2 fields (client_id, client_secret, refresh_token, token_url)
  2. TokenProvider implementation using the STS (Security Token Service) OAuth token endpoint specified in the credential file
  3. Conversion to AuthorizedUserCredentials for signing operations (same pattern as standard authorized_user)
  4. Builder integration to handle the new credential type in selection logic

The implementation follows the same OAuth2 refresh flow as standard authorized_user credentials, but uses the custom token_url endpoint (typically https://sts.googleapis.com/v1/oauthtoken) specified in the credential file.

Changes

Files Modified:

  • src/gcp/credential.rs: Added ExternalAccountAuthorizedUserCredentials struct, enum variant, and TokenProvider implementation
  • src/gcp/builder.rs: Updated credential selection logic to handle new type
  • src/gcp/mod.rs: Added integration test

Lines Changed: +314 additions across 3 files

Testing

Unit Tests

  • ✅ Deserialization with full JSON format
  • ✅ Deserialization with minimal required fields
  • ✅ Conversion to AuthorizedUserCredentials for signing
  • ✅ Builder construction with sample credentials

Integration Tests

  • ✅ End-to-end test with put/get/delete operations (when TEST_INTEGRATION=1)
  • ✅ Manual test with real ADC credentials (#[ignore])

Test Results:

test result: ok. 114 passed; 0 failed; 3 ignored

All existing tests continue to pass with no regressions.

Credential Format Example

{
  "type": "external_account_authorized_user",
  "audience": "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider",
  "client_id": "xxxxx.apps.googleusercontent.com",
  "client_secret": "secret",
  "refresh_token": "token",
  "token_url": "https://sts.googleapis.com/v1/oauthtoken",
  "token_info_url": "https://sts.googleapis.com/v1/introspect",
  "quota_project_id": "project-id"
}

Impact

This change enables users in enterprise environments with Workforce Identity Federation to use object_store with their standard ADC configuration, matching the behavior of official Google Cloud client libraries (Python, Java, Go, etc.).

References

Adds support for the external_account_authorized_user credential type used
by Google Cloud Workforce Identity Federation. This credential format is
created when users authenticate with `gcloud auth application-default login`
using workforce identity pools with external identity providers.

Previously, object_store only supported service_account and authorized_user
credential types, causing deserialization failures when ADC files contained
external_account_authorized_user credentials.

Changes:
- Added ExternalAccountAuthorizedUser variant to ApplicationDefaultCredentials enum
- Implemented ExternalAccountAuthorizedUserCredentials struct with OAuth2 fields
- Implemented TokenProvider trait using custom STS token endpoint
- Added conversion to AuthorizedUserCredentials for signing operations
- Updated builder.rs to handle new credential type in selection logic

The implementation uses the STS (Security Token Service) OAuth token endpoint
specified in the credential file for token refresh, following the same pattern
as standard authorized_user credentials but with configurable token_url.

Tests added:
- Unit tests for JSON deserialization (full and minimal formats)
- Unit test for credential type conversion
- Builder test with sample credentials
- Integration test for end-to-end API operations
- Manual test with real ADC credentials (#[ignore])

This enables users in enterprise environments with Workforce Identity Federation
to use object_store without workarounds, matching the behavior of official
Google Cloud client libraries.
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

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

Thanks @nazq


#[test]
#[ignore] // Only run manually when testing with real ADC
fn gcs_test_real_external_account_authorized_user_adc() {
Copy link
Contributor

Choose a reason for hiding this comment

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

this test seems more like an example -- I wonder if it would be better as an example (or a no-run doc test)

async fn gcs_test_external_account_authorized_user_integration() {
maybe_skip_integration!();

// This test verifies that external_account_authorized_user credentials
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand how this test is verifying external_account_authorized_user -- it doesn't seem to configure such credentials 🤔

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.

2 participants