Read gcloud Application Default Credentials from disk. Returns `(client_id, client_secret, refresh_token)`. Checks `GOOGLE_APPLICATION_CREDENTIALS` first; falls back to `$CLOUDSDK_CONFIG/application_default_credentials.json` when set, then to `~/.config/gcloud/application_default_credentials.json`.
()
| 4340 | /// `$CLOUDSDK_CONFIG/application_default_credentials.json` when set, then to |
| 4341 | /// `~/.config/gcloud/application_default_credentials.json`. |
| 4342 | fn read_gcloud_adc() -> Result<(String, String, String)> { |
| 4343 | let path = if let Some(env_path) = std::env::var("GOOGLE_APPLICATION_CREDENTIALS") |
| 4344 | .ok() |
| 4345 | .filter(|v| !v.is_empty()) |
| 4346 | { |
| 4347 | PathBuf::from(env_path) |
| 4348 | } else if let Some(config_dir) = std::env::var("CLOUDSDK_CONFIG") |
| 4349 | .ok() |
| 4350 | .filter(|v| !v.is_empty()) |
| 4351 | { |
| 4352 | PathBuf::from(config_dir).join("application_default_credentials.json") |
| 4353 | } else { |
| 4354 | let home = std::env::var("HOME") |
| 4355 | .map_err(|_| miette::miette!("HOME is not set; cannot locate gcloud ADC file"))?; |
| 4356 | PathBuf::from(home) |
| 4357 | .join(".config") |
| 4358 | .join("gcloud") |
| 4359 | .join("application_default_credentials.json") |
| 4360 | }; |
| 4361 | |
| 4362 | let content = std::fs::read_to_string(&path).map_err(|err| { |
| 4363 | miette::miette!( |
| 4364 | "failed to read gcloud ADC file at {}: {}. \ |
| 4365 | Run: gcloud auth application-default login", |
| 4366 | path.display(), |
| 4367 | err |
| 4368 | ) |
| 4369 | })?; |
| 4370 | |
| 4371 | let json: serde_json::Value = serde_json::from_str(&content) |
| 4372 | .map_err(|err| miette::miette!("failed to parse gcloud ADC file: {err}"))?; |
| 4373 | |
| 4374 | let cred_type = json.get("type").and_then(|v| v.as_str()); |
| 4375 | match cred_type { |
| 4376 | Some("service_account") => { |
| 4377 | return Err(miette::miette!( |
| 4378 | "Application Default Credentials are a service account key, not user credentials. \ |
| 4379 | To use a service account, create the provider with the service account JSON key \ |
| 4380 | and configure gateway-managed refresh for 'GOOGLE_VERTEX_AI_SERVICE_ACCOUNT_TOKEN'. \ |
| 4381 | See: openshell provider create --help" |
| 4382 | )); |
| 4383 | } |
| 4384 | Some("authorized_user") => {} |
| 4385 | Some(other) => { |
| 4386 | return Err(miette::miette!( |
| 4387 | "Application Default Credentials have unsupported type '{other}' \ |
| 4388 | (expected 'authorized_user'). \ |
| 4389 | Run: gcloud auth application-default login" |
| 4390 | )); |
| 4391 | } |
| 4392 | None => { |
| 4393 | return Err(miette::miette!( |
| 4394 | "gcloud ADC file is missing the 'type' field. \ |
| 4395 | The file may be malformed. \ |
| 4396 | Run: gcloud auth application-default login" |
| 4397 | )); |
| 4398 | } |
| 4399 | } |