peburrows / goth

Elixir package for Oauth authentication via Google Cloud APIs
http://hexdocs.pm/goth
MIT License
284 stars 108 forks source link

Support for workload identity federation credential file format #154

Closed gmile closed 5 months ago

gmile commented 1 year ago

Thanks for an awesome library, we at Contractbook are happy users! :hugs:

Would it be possible to add support for workload identity federation credential file format?

The file section "GOOGLE_APPLICATION_CREDENTIALS environment variable" of "How Application Default Credentials works" page lists two different types of contents for the JSON file: service account and configuration for workload identity federation. We're particularly interested in support for configuration for workload identity federation.

For context why we need this: we're gradually getting rid of all JSON service accounts across our infrastructure in favor of short-lived tokens issued as part of key-less approach, to improve our security posture.

One of the places where we still had some service accounts as JSON are ENV variables in GitHub Actions. After cleaning up our GH actions to use OIDC / work identity federation approach, it became clear that Goth doesn't recognize the different contents format for GOOGLE_APPLICATION_CREDENTIALS file, some of our Elixir code that needs to run as part of the CI fails to authenticate with Google Cloud.

The new format looks like this:

{
  "type": "external_account",
  "audience": "//iam.googleapis.com/***",
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
  "token_url": "https://sts.googleapis.com/v1/token",
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/***:generateAccessToken",
  "credential_source": {
    "url": "https://pipelines.actions.githubusercontent.com/f6c3c35b039387ef292397f8204b44f06dd59dd6c708753be0/00000000-0000-0000-0000-000000000000/_apis/distributedtask/hubs/Actions/plans/671d6379-83c9-4431-957a-99ccc35f7298/jobs/52d517d4-19eb-42f8-9cca-7dc7ce1e4b1a/idtoken?api-version=2.0&audience=https%3A%2F%2Fiam.googleapis.com%2F***",
    "headers": {
      "Authorization": "***"
    },
    "format": {
      "type": "json",
      "subject_token_field_name": "value"
    }
  }
}

P.S. as a potential point of reference, a related implementation appears to exist (I'm only saying "appears" because I am not sure what I found is correct) in Google Cloud auth client for JavaScript maintained by folks from Google.

P.P.S. To those having problems deciphering the official auth libraries, like myself, the algorithm of obtaining a short-lived access token appears to be described here: https://cloud.google.com/iam/docs/using-workload-identity-federation#rest. Leaving it here for future reference.

wojtekmach commented 1 year ago

Please send a PR!