Let’s talk about keyless authorization from GitHub Actions in GCP using IdP. How should we auth into GCP from GitHub Actions (it doesn't matter if we use our runners or GitHub runners)? What if we use terraform to configure GCP and GitHub Actions for our automation operations? The easiest and not the most secure way — is to create a primary GCP Service Account key (JSON) with specific permission and authorization. This is a great way to start. Let’s see how it works: It is straightforward, but what if: The service account key will be compromised? We want to limit the origins from where the key can be used. We want to reissue a new service account key automatically. Google has a great solution — . Workload Identity Federation Traditionally, applications running outside Google Cloud have used to access Google Cloud resources. Service account keys are powerful credentials, and can represent a security risk if they are not managed correctly. service account keys With identity federation, you can use Identity and Access Management (IAM) to grant external identities , including the ability to impersonate service accounts. This lets you access resources directly, using a , and eliminates the maintenance and security burden associated with service account keys. IAM roles short-lived access token You can use workload identity federation with the following: SAML 2.0 Any identity provider that supports OpenID Connect (OIDC), such as Microsoft Azure Amazon Web Services (AWS) A is an entity that describes a relationship between Google Cloud and an external identity provider, such as the following: workload identity pool provider AWS Azure Active Directory On-premises Active Directory Federation Services (AD FS) Okta Kubernetes clusters But let’s look at how to use this keyless authorization paired with GitHub Actions. On the Google Cloud side We will perform all the actions using terraform, but you can also use the UI GCP. First, let’s create Workload Identity Pool: resource "google_iam_workload_identity_pool" "github_actions" { provider = google-beta project = "my-gcp-project" workload_identity_pool_id = "github-actions" display_name = "GitHub Actions pool" description = "Workload Identity Pool managed by Terraform" disabled = false } Then we need to create a Workload Identity Pool Provider (many providers can be assigned to one Workload Identity Pool): resource "google_iam_workload_identity_pool_provider" "github_actions" { provider = google-beta project = "my-gcp-project" workload_identity_pool_id = google_iam_workload_identity_pool.github_actions.workload_identity_pool_id workload_identity_pool_provider_id = "github-actions" display_name = "GitHub Actions provider" description = "Workload Identity Pool Provider managed by Terraform" attribute_condition = "attribute.repository_owner==\"arslanbekov\"" attribute_mapping = { "google.subject" = "assertion.sub" "attribute.actor" = "assertion.actor" "attribute.aud" = "assertion.aud" "attribute.repository" = "assertion.repository" "attribute.repository_owner" = "assertion.repository_owner" } oidc { allowed_audiences = [] issuer_uri = "https://token.actions.githubusercontent.com" } } Notice the parameter , a condition by which we can that do not fall under our filter. attribute_condition prohibit actions You can see all available values in the official . GitHub documentation We also need a service account (don’t worry, we won’t need the keys anywhere); I did not describe it in the terraform code for simplicity; I think that you can easily do it yourself or using CLI gcloud: gcloud iam service-accounts create SA_NAME \ --description="DESCRIPTION" \ --display-name="DISPLAY_NAME" After we have an email service account, it will need to be given a role. roles/iam.workloadIdentityUser resource "google_service_account_iam_member" "wif-sa" { service_account_id = "projects/my-gcp-project/serviceAccounts/example-sa@my-gcp-project.iam.gserviceaccount.com" role = "roles/iam.workloadIdentityUser" member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_actions.name}/*" } Don’t forget to replace and my-gcp-project example-sa@my-gcp-project.iam.gserviceaccount.com After applying this terraform in the output, you will have two values (please save them, you will need them later): output "pool_name" { description = "Pool name" value = google_iam_workload_identity_pool.github_actions.name } output "provider_name" { description = "Provider name" value = google_iam_workload_identity_pool_provider.github_actions.name } Example output: pool_name = "projects/${redacted_number}/locations/global/workloadIdentityPools/github-actions" provider_name = "projects/${redacted_number}/locations/global/workloadIdentityPools/github-actions/providers/github-actions" On the GitHub side Let’s create 2 GitHub actions secrets: (need to specify the entire line, for example: ) GCP_WORKLOAD_IDENTITY_PROVIDER_NAME projects/123456789/locations/global/workloadIdentityPools/github-actions/providers/github-actions (service account email that we created earlier and indicated in the terraform) GCP_WORKLOAD_IDENTITY_SA_EMAIL GitHub workflow example: name: "Example Workload Identity" on: push: branches: - "master" jobs: run: name: "Workload Identity Job" permissions: id-token: write contents: read runs-on: "ubuntu-latest" steps: - name: "Auth in GCP" id: "auth" uses: "google-github-actions/auth@v1" with: token_format: "access_token" workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER_NAME }} service_account: ${{ secrets.GCP_WORKLOAD_IDENTITY_SA_EMAIL }} - name: "Docker login" run: | echo '${{ steps.auth.outputs.access_token }}' | docker login -u oauth2accesstoken --password-stdin https://gcr.io Finally, we can authorize in the docker which will be in the output of the step . access_token id: auth If you need interaction with — then this is also available after authorization. gsutils Conclusions By switching to authorization through a , we can restrict access from specific origins for approval. We also stop caring about key rotation and can control the key's lifetime. workload identity provider Links (you can find all the code described by terraform in this article in this repository) https://github.com/arslanbekov/wif-gcp-terraform (example github-actions auth) https://github.com/arslanbekov/wif-gcp-github-actions They are also published . here