Google Cloud Workload Identity Federation with Okta

Prashant Kulkarni
Google Cloud - Community
4 min readOct 16, 2021

If you’re new to Workload Identity Federation, take a look at this medium article and this blog from Scalesec. Basically Workload Identity Federation will allow you to connect to Google Cloud APIs without using a service account key from outside of Google Cloud. This reduces the risk of key leakage or misuse and remove one of the biggest hurdle in hybrid or multi-cloud integration.

Workload Identity Federation is not suitable in all scenarios. Here is a simple flowchart that describes the process of choosing Workload Identity Federation for your application.

In this article, we’re going to assume:

  • That you’ve the source code of the application that needs to query Google Cloud APIs
  • You’re using Okta as your OIDC provider
  • You’re using one of the supported programming language for google-auth libraries

OAuth Flow

We will be using Client Credentials Flow (defined in OAuth 2.0 RFC 6749, section 4.4), in which your application will pass along the Client ID and Client Secret to authenticate the application itself and get a token. Why? With machine-to-machine (M2M) applications, such as CLIs, daemons, or services running on your back-end, the system authenticates and authorizes the app rather than a user. For this scenario, typical authentication schemes like username + password or social logins don’t make sense. Instead, M2M apps use the OAuth Client Credentials Flow.

Here is a data flow that will happen in this case

Step to Prepare Okta for issuing Client credentials

Okta has a concept of authorization server that is needed to issue client credentials. In my test instance I had to create a new authorization server so that I can get an access token.

  1. Login to Okta admin console
  2. Go to Security->API
  3. Authorization Server
  4. Define a new authorization server , note the issuer URL — you’ll need this to configure OIDC provider in Google Cloud
  5. Set audience (could be anything that is mutually verifiable, preferably unique), note the audience — you’ll need this to configure OIDC provider in Google Cloud
  6. Define a new scope, set this scope as a default scope
  7. Define a new claim. Customize this claim to your requirement of attribute verification in Google Cloud
  8. Go to access policies, make sure its Assigned to “All Clients”

Google Cloud Setup

Create a Workload Identity Pool and a new provider for Okta. As Google Cloud OIDC provider doesn’t allow to set aud value, you’ll need to execute Step# 3 via gcloud. Other steps can be executed using console.

  1. gcloud iam workload-identity-pools create workload-id-pool1 — location=”global” — description=”Testing workload identity federation with Okta ” — display-name=”workload-id-pool1"
  2. gcloud iam workload-identity-pools providers create-oidc okta-provider — workload-identity-pool=”workload-id-pool1" — issuer-uri=”<okta-issuer-url>" — location=”global” — attribute-mapping=”google.subject=assertion.sub” — allowed-audiences=”<ENTER CLIENT_ID>”
  3. gcloud iam service-accounts add-iam-policy-binding oktagcpsvacct@ps-test-project-259122.iam.gserviceaccount.com — role=roles/iam.workloadIdentityUser — member=”principal://iam.googleapis.com/projects/731056981369/locations/global/workloadIdentityPools/workload-id-pool-1/subject/<authz-server-sub>"
  4. gcloud beta iam workload-identity-pools providers update-oidc vz-sso-oidc2 — allowed-audiences=”api://24wwds23" — workload-identity-pool=”workload-id-pool1" — location=”global”

Use this gcloud command to verify that the aud and sub are set correctly

gcloud iam workload-identity-pools providers describe okta-provider — workload-identity-pool=”workload-id-pool1" — location=”global”

2. Download the JSON config file and store in your application repository. This file can live with application as it has no confidential data like private key.

The JSON config file look like this:

{
"type": "external_account",
"audience": "//iam.googleapis.com/projects/794301636481/locations/global/workloadIdentityPools/okta-pool-1/providers/google-sec-okta",
"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/oktagcpsvacct@ps-test-project-259122.iam.gserviceaccount.com:generateAccessToken",
"credential_source": {
"file": "/tmp/okta-token.json",
"format": {
"type": "json",
"subject_token_field_name": "access_token"
}
}
}

As you can see this new JSON file looks quite different than the original key json file. This json file instructs the google-auth library on what end points to use for STS and Service Account and how to lookup the Workload identity pool. The audience value in the json file doesn’t need to match within Okta. As long as the audience configured in Okta authorization server , the provider and JWT token matches, we’re good.

This json file also instructs the google-auth library where to find the Okta access toke jsons so make sure the “file” parameter includes the path to the json file and the name of the file as seen above.

Here is a sample client code that queries Okta to get an access token, stores in the file system and delete it when the client program done running.

--

--

Prashant Kulkarni
Google Cloud - Community

A proud Googler! Cloud Security and Astronomy junkie. Loves dogs and cats! Opinions are of my own.