We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Workload Identity Federation

We want to add an Artifact Registry step to the continuous delivery pipeline. gcloud builds submit works from your laptop using your Google account identity. Which identity would you use from GitHub Actions?

We can use Workload Identity Federation (WIF). Federation here means allowing an identity from one system to be trusted by another. We want Google Cloud to trust an identity from GitHub Actions. This is much better than long-lived credentials that need to be kept secret and regularly rotated. These two steps have proven challenging for many an organization.

How It Works

The federation between GitHub and GCP is powered by OpenID Connect (OIDC).

  1. In the GitHub Actions workflow, GitHub makes a signed OIDC token available. The token contains information about the running workflow, including its repository and branch.
  2. The google-github-actions/auth GitHub Action sends the OIDC token and the service account we want to use to GCP.
  3. If the GitHub identity is allowed to impersonate the service account, GCP returns short-lived credentials for the service account.
  4. Now the workflow can use gcloud builds submit with the permissions of the service account.

Pools and Providers

We configure two things in GCP:

  • A workload identity pool groups external identities.
  • A workload identity provider defines how to verify a token from an external identity provider, like GitHub.

We don't want to trust EVERY token from GitHub - that would allow access from ANY workflow from ANY GitHub user. You can write rules in the provider to restrict access to your repository or a particular branch.

Assignment

There are going to be a lot of gcloud commands here. Making things secure does take extra steps.

Creating a Service Account

Configuring WIF

The Configure Workload Identity Federation with deployment pipelines documentation explains the APIs we're enabling and the resources we're creating.

    • Identity and Access Management (IAM) API
    • Cloud Resource Manager API
    • IAM Service Account Credentials API
    • Security Token Service API
  1. GCP_PROJECT_ID="$(gcloud config get-value project)"
    GCP_SERVICE_ACCOUNT_EMAIL="cloud-run-deployer@${GCP_PROJECT_ID}.iam.gserviceaccount.com"
    GITHUB_REPO="$(git remote get-url origin | sed -E 's#.*github.com[:/]##; s#\.git$##')"
    
    echo "
    GCP Project:         ${GCP_PROJECT_ID}
    GCP Service Account: ${GCP_SERVICE_ACCOUNT_EMAIL}
    GitHub Repo:         ${GITHUB_REPO}
    "
    
  2. gcloud iam workload-identity-pools create "github" \
      --location="global" \
      --display-name="GitHub Actions Pool"
    
  3. The issuer URL identifies GitHub's OIDC provider. If you're curious, you can see the public keys used to verify GitHub's OIDC tokens.

    gcloud iam workload-identity-pools providers create-oidc "my-repo" \
      --location="global" \
      --workload-identity-pool="github" \
      --display-name="My GitHub repo Provider" \
      --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \
      --attribute-condition="assertion.repository == '${GITHUB_REPO}'" \
      --issuer-uri="https://token.actions.githubusercontent.com"
    
  4. export WORKLOAD_IDENTITY_POOL="$(
      gcloud iam workload-identity-pools describe "github" \
        --location="global" \
        --format="value(name)"
    )"
    
  5. gcloud iam service-accounts add-iam-policy-binding \
      ${GCP_SERVICE_ACCOUNT_EMAIL} \
      --role=roles/iam.workloadIdentityUser \
      --member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL}/attribute.repository/${GITHUB_REPO}"
    

Run and submit the CLI tests from the root of your repo.