REPRO CASE
- Create a Service account in GCP (if you don't have one)
- Create a user account in GCP (you probably have one)
- Allow the user account to run as (impersonate) the service account
- Run
gcloud auth application-default login --impersonate-service-account=SERVICE-ACCOUNT-NAME
- Login as your user account
- Start R and run
gargle::credentials_app_default() (or something that calls it, like gargle::token_fetch or bigrquery::bq_auth())
Expected behavior: Successfully authenticates and acquires a token that authenticates as the service account, OR, fails in some explicit way (at least when debugging is enabled via options(gargle_quiet = FALSE))
Actual behavior: Prints that it found an ADC file, but then returns NULL instead of a token:
> print(gargle::credentials_app_default())
trying `credentials_app_default()`
file exists at ADC path:
/root/credentials.json
NULL
EXPLANATION
Impersonation credentials are a relatively new and relatively obscure but very useful and increasingly supported type of credentials for GCP, see:
Here is what these "impersonation credentials" look like:
{
"delegates": [],
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<SERVICE ACCOUNT NAME>",
"source_credentials": {
"client_id": "<USER CLIENT ID>",
"client_secret": "<USER CLIENT SECRET>",
"refresh_token": "<USER REFRESH TOKEN>",
"type": "authorized_user"
},
"type": "impersonated_service_account"
}
As you can see, they include a nested set of user credentials, plus instructions for how to use an API to get a token that impersonates the service account (without directly having the service account's credentials). The idea is that when fetching a token for these credentials, first you fetch a token for the nested user credentials, then you use that token to fetch a token to impersonate the service account, then you use that token.
At the very least, credentials_app_default.R should issue some sort of message if it falls of the end of the recognized info$type conditions, so that we'd see something like unknown ADC cred type: "impersonated_service_account" and have a clue about what's going wrong. Better yet, of course, would be to in fact support this type of credential properly...!