image pull secret
Google Container Registry
authentication
Kubernetes
cloud computing

Creating image pull secret for google container registry that doesn't expire?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you need Kubernetes to pull private images from Google Container Registry without rotating short-lived access tokens, the usual approach is a service account key stored as an image pull secret. That secret does not “expire” on a timer, but it remains valid only until you revoke, rotate, or disable the key. As of March 11, 2026, Google’s newer recommendation is to prefer Artifact Registry and short-lived identity mechanisms where possible, because long-lived keys are a security tradeoff.

What “Doesn’t Expire” Really Means

A normal OAuth access token expires quickly. A JSON service account key is different: it is a long-lived credential file. Kubernetes can use it repeatedly because the registry login is derived from that key whenever the secret is used.

That is convenient, but it also means anyone who gets the key can keep pulling your private images until you revoke the key. So the right mental model is not “permanent secret.” It is “long-lived credential that survives until rotated.”

When You Need an Image Pull Secret at All

On GKE, you may not need an image pull secret if the nodes already have permission to pull from the registry. On other Kubernetes clusters, or when cross-project access is involved, a registry secret is often the simplest option.

If you are still using Google Container Registry, be aware that Google announced Container Registry shutdown milestones in 2025, with writes disabled on March 18, 2025 and reads disabled on June 03, 2025. For new systems, Artifact Registry is the replacement. The same long-lived-key pattern still exists, but the preferred overall direction is keyless or short-lived identity where possible.

Create a Service Account With Minimal Access

Create a dedicated service account and grant only the role needed for pulling images. Avoid using broad project-owner permissions.

bash
1gcloud iam service-accounts create k8s-image-puller \
2  --display-name="Kubernetes image puller"
3
4gcloud projects add-iam-policy-binding PROJECT_ID \
5  --member="serviceAccount:k8s-image-puller@PROJECT_ID.iam.gserviceaccount.com" \
6  --role="roles/storage.objectViewer"

For Artifact Registry, the pull role would usually be an Artifact Registry reader role instead of the older storage-based permission model used by GCR.

Create the JSON Key

Generate a key file and keep it out of source control.

bash
gcloud iam service-accounts keys create key.json \
  --iam-account=k8s-image-puller@PROJECT_ID.iam.gserviceaccount.com

This file is the sensitive long-lived credential. Treat it like a password.

Create the Kubernetes Docker Registry Secret

For Google registries, the username is commonly _json_key and the password is the JSON file contents.

bash
1kubectl create secret docker-registry gcr-pull-secret \
2  --docker-server=https://gcr.io \
3  --docker-username=_json_key \
4  --docker-password="$(cat key.json)" \
5  --docker-email="[email protected]"

If you are using another registry host such as us.gcr.io, use that host for --docker-server.

Attach the Secret to a Pod or Service Account

You can reference the secret directly in a pod spec:

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: demo
5spec:
6  containers:
7    - name: app
8      image: gcr.io/PROJECT_ID/my-app:latest
9  imagePullSecrets:
10    - name: gcr-pull-secret

Or attach it to a service account so multiple pods inherit the setting:

bash
kubectl patch serviceaccount default \
  -p '{"imagePullSecrets":[{"name":"gcr-pull-secret"}]}'

Using a dedicated application service account is usually cleaner than patching the namespace default.

Security Tradeoffs and Better Alternatives

A long-lived image pull secret is convenient, but it is not the safest option. Google now steers users toward newer identity flows, especially for Artifact Registry and managed Kubernetes environments. Workload Identity or node-level access is preferable when available because there is no static JSON key sitting in a secret.

Still, if you are on a non-GKE cluster or integrating across environments, the JSON-key secret remains a valid operational pattern. Just treat it as a compromise and manage it deliberately.

Common Pitfalls

The first pitfall is calling the secret non-expiring and then forgetting it exists. It may not expire automatically, but it should still be rotated and audited.

Another mistake is granting overly broad IAM roles. Pulling images does not require administrative access to the whole project.

Developers also mix up GCR and Artifact Registry endpoints. The registry host in the secret must match the registry you are actually using.

Finally, avoid checking key.json into a repository or baking it into a container image. The point of the secret is to keep the credential out of your deployable artifacts.

Summary

  • A Kubernetes image pull secret can be made long-lived by using a Google service account JSON key.
  • The secret does not expire automatically, but it remains valid until you rotate or revoke the underlying key.
  • For current Google Cloud usage, Artifact Registry and keyless or short-lived identity mechanisms are preferred over static keys when possible.
  • If you do use a long-lived secret, grant minimal permissions and store the key carefully.
  • Match the registry host, IAM role, and Kubernetes secret configuration to the actual registry you are pulling from.

Course illustration
Course illustration

All Rights Reserved.