Skip to content

Commit 521f1dc

Browse files
authored
fix(gcp): ignore ADC errors when explicit credentials are provided (#531)
* fix(gcp): ignore ADC errors when explicit credentials are provided Previously, GoogleCloudStorageBuilder unconditionally attempted to read Application Default Credentials (ADC), causing build failures when ADC files existed in unsupported formats (e.g., external_account_authorized_user), even when explicit credentials were provided via with_service_account_path(), with_service_account_key(), or with_credentials(). This change makes ADC reading conditional: - When explicit credentials are provided, ADC reading errors are ignored - When no explicit credentials exist, ADC errors are propagated normally This preserves error visibility for users relying on ADC while allowing users with explicit credentials to work regardless of ADC state. The credential precedence remains: explicit credentials > ADC > instance metadata Tests added: - Verify explicit service account path ignores invalid ADC - Verify explicit service account key ignores invalid ADC - Verify custom credentials provider ignores invalid ADC - Verify ADC errors still propagate when no explicit credentials provided * refactor: skip ADC read when explicit credentials provided Per reviewer feedback, avoid unnecessary file I/O by returning None directly instead of attempting to read ADC and discarding errors.
1 parent 37ee020 commit 521f1dc

File tree

1 file changed

+116
-1
lines changed

1 file changed

+116
-1
lines changed

src/gcp/builder.rs

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,15 @@ impl GoogleCloudStorageBuilder {
491491
};
492492

493493
// Then try to initialize from the application credentials file, or the environment.
494+
// Only attempt to read ADC if no explicit credentials were provided
494495
let application_default_credentials =
495-
ApplicationDefaultCredentials::read(self.application_credentials_path.as_deref())?;
496+
if service_account_credentials.is_none() && self.credentials.is_none() {
497+
// No explicit credentials, so try ADC and propagate errors
498+
ApplicationDefaultCredentials::read(self.application_credentials_path.as_deref())?
499+
} else {
500+
// Explicit credentials provided, skip ADC reading entirely
501+
None
502+
};
496503

497504
let disable_oauth = service_account_credentials
498505
.as_ref()
@@ -746,4 +753,112 @@ mod tests {
746753
panic!("{key} not propagated as ClientConfigKey");
747754
}
748755
}
756+
757+
#[test]
758+
fn gcs_test_explicit_creds_skip_invalid_adc() {
759+
// Create a valid service account key file
760+
let mut valid_key_file = NamedTempFile::new().unwrap();
761+
write!(valid_key_file, "{FAKE_KEY}").unwrap();
762+
763+
// Create invalid ADC file with unsupported credential type
764+
let mut invalid_adc_file = NamedTempFile::new().unwrap();
765+
invalid_adc_file
766+
.write_all(br#"{"type": "external_account_authorized_user", "audience": "test"}"#)
767+
.unwrap();
768+
769+
// Build should succeed because explicit credentials are provided
770+
// and ADC errors should be ignored
771+
let result = GoogleCloudStorageBuilder::new()
772+
.with_service_account_path(valid_key_file.path().to_str().unwrap())
773+
.with_application_credentials(invalid_adc_file.path().to_str().unwrap())
774+
.with_bucket_name("test-bucket")
775+
.build();
776+
777+
// Should succeed - ADC errors should be ignored when explicit creds provided
778+
assert!(
779+
result.is_ok(),
780+
"Build should succeed with explicit credentials despite invalid ADC: {:?}",
781+
result.err()
782+
);
783+
}
784+
785+
#[test]
786+
fn gcs_test_explicit_creds_with_service_account_key_skip_invalid_adc() {
787+
// Create invalid ADC file with unsupported credential type
788+
let mut invalid_adc_file = NamedTempFile::new().unwrap();
789+
invalid_adc_file
790+
.write_all(br#"{"type": "external_account_authorized_user", "audience": "test"}"#)
791+
.unwrap();
792+
793+
// Build should succeed with service account key (not path)
794+
let result = GoogleCloudStorageBuilder::new()
795+
.with_service_account_key(FAKE_KEY)
796+
.with_application_credentials(invalid_adc_file.path().to_str().unwrap())
797+
.with_bucket_name("test-bucket")
798+
.build();
799+
800+
// Should succeed - ADC errors should be ignored when explicit creds provided
801+
assert!(
802+
result.is_ok(),
803+
"Build should succeed with service account key despite invalid ADC: {:?}",
804+
result.err()
805+
);
806+
}
807+
808+
#[test]
809+
fn gcs_test_adc_error_propagated_without_explicit_creds() {
810+
// Create invalid ADC file with unsupported credential type
811+
let mut invalid_adc_file = NamedTempFile::new().unwrap();
812+
invalid_adc_file
813+
.write_all(br#"{"type": "external_account_authorized_user", "audience": "test"}"#)
814+
.unwrap();
815+
816+
// Build should fail because no explicit credentials and ADC is invalid
817+
let result = GoogleCloudStorageBuilder::new()
818+
.with_application_credentials(invalid_adc_file.path().to_str().unwrap())
819+
.with_bucket_name("test-bucket")
820+
.build();
821+
822+
// Should fail - ADC errors should be propagated when no explicit creds
823+
assert!(
824+
result.is_err(),
825+
"Build should fail without explicit credentials and invalid ADC"
826+
);
827+
let err_msg = result.unwrap_err().to_string();
828+
assert!(
829+
err_msg.contains("external_account_authorized_user"),
830+
"Error should mention unsupported credential type: {}",
831+
err_msg
832+
);
833+
}
834+
835+
#[test]
836+
fn gcs_test_with_credentials_skip_invalid_adc() {
837+
use crate::StaticCredentialProvider;
838+
839+
// Create invalid ADC file with unsupported credential type
840+
let mut invalid_adc_file = NamedTempFile::new().unwrap();
841+
invalid_adc_file
842+
.write_all(br#"{"type": "external_account_authorized_user", "audience": "test"}"#)
843+
.unwrap();
844+
845+
// Create a custom credential provider
846+
let custom_creds = Arc::new(StaticCredentialProvider::new(GcpCredential {
847+
bearer: "custom-token".to_string(),
848+
}));
849+
850+
// Build should succeed with custom credentials provider despite invalid ADC
851+
let result = GoogleCloudStorageBuilder::new()
852+
.with_credentials(custom_creds)
853+
.with_application_credentials(invalid_adc_file.path().to_str().unwrap())
854+
.with_bucket_name("test-bucket")
855+
.build();
856+
857+
// Should succeed - ADC errors should be ignored when explicit creds provided via with_credentials
858+
assert!(
859+
result.is_ok(),
860+
"Build should succeed with custom credentials despite invalid ADC: {:?}",
861+
result.err()
862+
);
863+
}
749864
}

0 commit comments

Comments
 (0)