google-auth-library-php icon indicating copy to clipboard operation
google-auth-library-php copied to clipboard

Bug in ExternalAccess class

Open mruell opened this issue 11 months ago • 1 comments

Hi team!

The issue below is currently blocking us from using the servcie account impersonalisation together with the workload identity federation.

We would be really happy if you coul look into that. Thanks!

Environment details

  • OS: tested with MacOS and Linux
  • PHP version: 8.4
  • Package name and version: google/auth v1.45.3 (via packagist)

Steps to reproduce

Using federated workload access, with serviceaccount impersonalisation

Code example

Env

GOOGLE_APPLICATION_CREDENTIALS=/etc/workload-identity/credential-configuration.json

/etc/workload-identity/credential-configuration.json is

{
  "universe_domain": "googleapis.com",
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/xxx/locations/global/workloadIdentityPools/xxx/providers/xxx",
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "file": "/var/run/service-account/token",
    "format": {
      "type": "text"
    }
  },
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/[email protected]:generateAccessToken"
}

What happens

Every, but the first call to any google API will not use the impersonated service account and thus calls will fail with permission denied.

Description

The getLastReceivedToken method in the ExternalAccountCredentials class does not return the last received token, if $this->serviceAccountImpersonationUrl is beeing used.

The RequestWrapper that is beeing used by almost all official gcp client libraries will enforce the credential fetchers to be wrapped in a FetchAuthTokenCache instance.

The FetchAuthTokenCache instace will use updateMetadata to inject the access tokens in e.g. http calls. To do that it's using fetchAuthTokenFromCache to fetch the cache. But using getLastReceivedToken to get the token to cache.

Since getLastReceivedToken does not return the service account token, every call but the first, will not use the service account token and thus this functionality will fail.

I'd be really happy if you could look into this :)

Thanks a lot in advance and best, Marvin

mruell avatar Feb 04 '25 13:02 mruell

I already opened a PR that should solve this issue https://github.com/googleapis/google-auth-library-php/pull/604

mruell avatar Feb 04 '25 13:02 mruell