Skip to content

application_default_credentials() doesn't support "impersonated_service_account" credentials (and gives confusing messages) #266

Open
@egnor

Description

@egnor

REPRO CASE

  1. Create a Service account in GCP (if you don't have one)
  2. Create a user account in GCP (you probably have one)
  3. Allow the user account to run as (impersonate) the service account
  4. Run gcloud auth application-default login --impersonate-service-account=SERVICE-ACCOUNT-NAME
  5. Login as your user account
  6. 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...!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions