← Back to list

How to securely push Docker images from GitHub Actions to Google Artifact Registry

This article will detail how to set up a CI/CD pipeline using Github Actions to build and push Docker images to a hosted registry like…

Kay Wilkinson · 2025-10-02 11:02 · 0 claps · 4.5 min read
#google-artifact-registry #github-actions #continuous-deployment #docker-image #workload-identity
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud 🔓 · Open Source 🏺 · Archaeology & Anthropology

How to securely push Docker images from GitHub Actions to Google Artifact Registry

This article will detail how to set up a CI/CD pipeline using Github Actions to build and push Docker images to a hosted registry like Google Artifact Registry (GAR). This is core to modern deployment practices as you can just push code changes to your repository and automatically provision those changes on a deployed environment; production, development, acceptance, etc.

The “secure” part:

To push images the most secure way, we are going to use GCP Workload Identity Federation. It’s more secure as we don’t need to store GCP Service Account keys in our Github Secrets. This limits the exposure of sensitive information that could be exploited by a malicious user.

What you need to get started:

  • A GCP project
  • A Github repository with Github Actions enabled (it should be enabled by default)
  • Your Docker image is defined with a Dockerfile and optionally deployed to Cloud Run

Step One: Set up GAR:

First, lets enable GAR and set up a repository to store our artifacts. Go to the Artifact Registry page and enable GAR. If you are having some trouble with this, enable the API with this link. Then follow the below steps

  1. Click Create Repository.
  2. Enter the following:
  • For Name, give the repository a name that makes sense.
  • For Format, select “Docker”.
  • For Region, select the region closest to you

Optional:

You can set up a clean up policy on the registry to avoid it getting too bloated. This won’t be applicable for all use cases — for example, sometimes artifacts need to be kept for a long period of time due to business, regulatory or legal reasons. For the needs of this tutorial, it is useful. I set up a clean up policy to delete artifacts that are > 20 versions old. This way I can still rollback changes easily. But it is unlikely I’d need to rollback to such an old version. Therefore, deleting these artifacts is perfectly fine.

Click create and proceed to the next step. You have just created a repository on GAR.

Step Two: Create a Workload Identity Pool and attribute a Github OIDC User to it

This step will cover creating a Workload Identity Pool and attaching a Github user to that pool. We need to follow these steps so the Github Action is able to write to GAR.

First, start by opening the CloudShell in the GCP console for your project.

Paste the following into the terminal of CloudShell to create a Workload Identity Pool:

gcloud iam workload-identity-pools create "github-pool" \
  --location="global" \
  --display-name="GitHub Actions Pool"

Create an OIDC Provider for Github Actions

Next, get the following details from Github:

  1. Your Github username
  2. Your Github repository name Replace the REPLACEME* values in the below snippet with those values and run in the CloudShell terminal.
gcloud iam workload-identity-pools providers create-oidc "github-provider" \
  --location="global" \
  --workload-identity-pool="github-pool" \
  --display-name="GitHub Actions Provider" \
  --issuer-uri="https://token.actions.githubusercontent.com" \
  --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.aud=assertion.aud,attribute.repository=assertion.repository" \
  --attribute-condition="assertion.repository == 'REPLACE_ME_WITH_GITHUB_USERNAME/REPLACE_ME_WITH_GITHUB_REPO_NAME'"

The above command creates the OIDC provider for Github.

Good to Know: We do this because we want Google Cloud to trust GitHub Actions as an identity provider, so it can verify who is calling it from GitHub and grant permissions securely without using service account keys.

Create a Service Account & give it permissions

Then, we need to create a service account for Github so it can be tied to Workload Identity.

gcloud iam service-accounts create github-ci \
  --display-name="GitHub Actions CI"

Then grant this service account permissions so it can write to GAR, thereby being able to publish Docker images to that repository. Replace the REPLACEME* value in the code snippet below with your GCP project ID and run the following in CloudShell.

gcloud projects add-iam-policy-binding REPLACE_ME_GCP_PROJECT_ID \
  --member="serviceAccount:github-ci@REPLACE_ME_GCP_PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/artifactregistry.writer"

For the next step, we need the GCP Project Number. Use the following snippet to retrieve it (again, replace the REPLACEME* value below):

gcloud projects describe REPLACE_ME_GCP_PROJECT_ID --format="value(projectNumber)"

Link the Service Account to the WIP

Finally, we bind the service account for Github Actions to the Workload Identity Pool. Replace the three REPLACEME* values in the below snippet and run it in CloudShell:

gcloud iam service-accounts add-iam-policy-binding github-ci@REPLACE_ME_GCP_PROJECT_ID.iam.gserviceaccount.com \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/149690229467/locations/global/workloadIdentityPools/github-pool/attribute.repository/REPLACE_ME_WITH_GITHUB_USERNAME/REPLACE_ME_WITH_GITHUB_REPO_NAME"

Step Three: Configure GitHub Secrets

In your GitHub repo → Settings → Secrets and variables → Actions, add the following to “Repository Secrets”:

  • GCP_PROJECT_ID:
  • GCP_SA_EMAIL: github-ci@REPLACE_ME_GCP_PROJECT_ID.iam.gserviceaccount.com
  • GCP_WORKLOAD_PROVIDER:

You can retrieve your GCP_WORKLOAD_PROVIDER from CloudShell using the following:

gcloud iam workload-identity-pools providers describe github-provider \
  --location=global --workload-identity-pool=github-pool \
  --format="value(name)"

Step Four: Create a Github Action

Finally, we create a Github Action in our Github repository so we can build and push Docker images to GAR.

In your codebase, create a directory for your Github Actions:

mkdir -r .github/workflows/

Then create a yaml file for our deploy action:

touch .github/workflows/deploy.yml

Paste the following into the new yaml file:

name: Build & Push Docker Image to Artifact Registry

on:
  push:
    branches: [main]

jobs:
  build-push:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v2
        with:
          token_format: 'id_token'
          workload_identity_provider: ${{ secrets.GCP_WORKLOAD_PROVIDER }}
          service_account: ${{ secrets.GCP_SA_EMAIL }}

      - name: Set up gcloud CLI
        uses: google-github-actions/setup-gcloud@v1

      - name: Configure Docker for Artifact Registry
        run: gcloud auth configure-docker europe-west4-docker.pkg.dev

      - name: Build and Push Docker image
        run: |
          IMAGE_URI="europe-west4-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/YOUR_GAR_REPO_NAME/YOUR_DOCKER_IMAGE_NAME:${{ github.sha }}"
          docker build -t "$IMAGE_URI" .
          docker push "$IMAGE_URI"

Change the values in the last stage (“Build and Push Docker image”): YOUR_GAR_REPO_NAME/YOUR_DOCKER_IMAGE_NAME

Then push the code to your repository.

Validate the CI/CD job

Go to the Actions tab in the repository. You should see the build executing.

Verify the Action has published the image to the registry by checking in GAR: https://console.cloud.google.com/artifacts/docker/REPLACE_ME_GCP_PROJECT_ID/europe-west4/REPLACE_ME_GAR_REPO_NAME?project=REPLACE_ME_GCP_PROJECT_ID

Click on the image to view the digest:

This article was originally published on vibecodingrevival.com


메타데이터
post_id
0972ed554b64
slug
how-to-securely-push-docker-images-from-github-actions-to-google-artifact-registry-0972ed554b64
url
https://medium.com/@hkayw95/how-to-securely-push-docker-images-from-github-actions-to-google-artifact-registry-0972ed554b64
canonical_url
https://medium.com/@hkayw95/how-to-securely-push-docker-images-from-github-actions-to-google-artifact-registry-0972ed554b64
author_url
https://medium.com/@hkayw95
status
ok
fetched_at
2026-07-30 18:47:05