-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Describe the bug
When we use impersonated_service_account type credential. ServiceAccountCredentialExchanger is unable to exchange access token
To Reproduce
Steps to reproduce the behavior:
- Create python env
uv venv --python 3.13.3
- activate python env
source .venv/bin/activate
- install adk
uv init
uv add google-adk==1.6.1
- Setup gcloud confic
gcloud config configurations create <name>
gcloud config set project <project>
gcloud config set auth/impersonate_service_account shared-service-account@<project>.iam.gserviceaccount.com
gcloud config set account <user account>
gcloud auth application-default login
- Make sure application_default_credentials.json is generated
(.venv) user@abehsu-us-vscode:$ cat ~/.config/gcloud/application_default_credentials.json
{
"delegates": [],
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/shared-service-account@<project>.iam.gserviceaccount.com:generateAccessToken",
"source_credentials": {
"account": "",
"client_id": "",
"client_secret": "",
"refresh_token": "1",
"type": "authorized_user",
"universe_domain": "googleapis.com"
},
"type": "impersonated_service_account"
}
- Execute this python code
from google.adk.tools.openapi_tool.auth.credential_exchangers import ServiceAccountCredentialExchanger
from google.adk.auth import AuthCredentialTypes
from google.adk.auth.auth_credential import AuthCredential
from google.adk.auth.auth_credential import AuthCredentialTypes
from google.adk.auth.auth_credential import ServiceAccount
from fastapi.openapi.models import HTTPBearer
auth_credential = AuthCredential(
auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
service_account=ServiceAccount(
use_default_credential=True,
scopes=[
"https://www.googleapis.com/auth/cloud-platform"
],
),
)
auth_schema = HTTPBearer(bearerFormat="JWT")
service_account_exchanger = ServiceAccountCredentialExchanger()
service_account_exchanger.exchange_credential(
auth_schema
,auth_credential
)
Error:
google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger.AuthCredentialMissingError: Failed to exchange service account token: ('Unable to acquire impersonated credentials', '{\n "error": {\n "code": 400,\n "message": "Request contains an invalid argument.",\n "status": "INVALID_ARGUMENT"\n }\n}\n')
Expected behavior
when exchange_credential execute credentials.refresh(Request()), it should able to handle impersonated_service_account type credential to get access token
Desktop (please complete the following information):
- Python version(python -V): 3.13.3
- ADK version(pip show google-adk): 1.6.1
Propose Solution
The reason of this is because the code doesn't provide scope when it execute google.auth.default(), we should provide "https://www.googleapis.com/auth/cloud-platform" as scope like this [1]
[1] https://github.com/googleapis/python-genai/blob/main/google/genai/_api_client.py#L185