Blog

How to configure Google Cloud Workload Identity Federation for Azure DevOps

06 Apr, 2024
Xebia Background Header Wave

Deploying Google Cloud (GCP) resources via Azure Pipelines used to require service account keys. Today, however, Azure DevOps OIDC tokens can be exchanged to Google credentials using Google Cloud Workload Identity Federation.

Google Cloud Workload Identity Federation

External workloads can access Google Cloud resources using workload identity federation, without using a service account key. Workload identity federation follows the OAuth 2.0 token exchange specification. You provide the workload’s credential from your IdP to the Google Security Token Service, which verifies the identity on the credential, and then returns a federated token in exchange.

Azure DevOps Tokens

Azure Pipelines use Service Connections to access external resources. Consequently, Azure DevOps issues OIDC tokens to prove that you are allowed to access an external resource:

{
  ..
  "sub": "sc://devops-organization/devops-project/service-connection-name",
  "aud": "api://AzureADTokenExchange",
  "iss": "https://vstoken.dev.azure.com/devops-organization-id",
  ..
}

These tokens are issued by your Azure DevOps organization (account) for a fixed purpose bound to the service connection. The token is trustworthy, because an Azure Pipeline needs to be granted access to the Service connection.

Tip! Find your Azure DevOps organization ID using the Accounts API. Check this example.

Federating Azure DevOps Tokens

The Workload Identity Pool Provider maps the Azure DevOps tokens to Google credentials:

resource "google_iam_workload_identity_pool_provider" "azure_devops_organization" {
  workload_identity_pool_id          = google_iam_workload_identity_pool.example.workload_identity_pool_id
  workload_identity_pool_provider_id = "ado-org"
  display_name                       = "ado/org"
  disabled                           = false

  attribute_mapping = {
    "google.subject" = "assertion.sub"
  }

  oidc {
    issuer_uri = "https://vstoken.dev.azure.com/00000000-0000-0000-0000-000000000000"
    allowed_audiences = [
      "api://AzureADTokenExchange"
    ]
  }
}

Find the complete example on GitHub.

Allowing you to get a Google credential:

POST https://sts.googleapis.com/v1/token
{
  "audience": "//iam.googleapis.com/projects/0000/locations/global/workloadIdentityPools/example/providers/ado-org`,
  "grantType": "urn:ietf:params:oauth:grant-type:token-exchange",
  "requestedTokenType": "urn:ietf:params:oauth:token-type:access_token",
  "scope": "https://www.googleapis.com/auth/cloud-platform",
  "subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
  "subjectToken": "eyJ0eXAiOiJKV1Q..."
}

Impersonating Service Accounts

Finally, the Google credential can be used to impersonate a specific service account:

resource "google_service_account_iam_member" "azure_devops_workload_identity_user" {
  service_account_id = google_service_account.azure_devops_project.name
  role               = "roles/iam.workloadIdentityUser"
  member             = "principal://iam.googleapis.com/${google_iam_workload_identity_pool.azure_devops_organization.name}/subject/sc://my-organization/my-project/my-connection"
}
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa@project.iam.gserviceaccount.com:generateAccessToken
Authorization: "Bearer ..."
{
  "scope": "https://www.googleapis.com/auth/cloud-platform"
}

Conclusion

Stop using service account keys. Federate Google credentials based on Azure DevOps OIDC tokens representing Service Connections.

Image by jacqueline macou from Pixabay

Laurens Knoll
As a cloud consultant I enjoy taking software engineering practices to the cloud. Continuously improving the customers systems, tools and processes by focusing on integration and quality.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts