Authenticate GCP for Cluster Shield

When running container vulnerability management, Cluster Shield pulls images from registries that may require authentication. When interacting with Google Container Registry (GCR) or Google Artifact Registry (GAR), Cluster Shield can authenticate to the registry through a service account key or through the docker credential helper. This topic provides instructions on how to correctly configure Cluster Shield with GCR and GAR and how to troubleshoot authentication issues.

Cluster Shield supports two primary authentication methods:

Authenticate Using Docker Credential Helper

Docker Credential Helper utilizes Google Application Default Credentials (ADC). ADC is Google’s recommended strategy by which authentication libraries can automatically find credentials based on the application environment. These credentials are used by Cluster Shield to authenticate to the remote registry.

Google Cloud Attached Service Account

GKE Autopilot clusters automatically attach service accounts; no manual configuration is required.

  1. Create Minimally Privileged Service Account:

    gcloud iam service-accounts create SA_NAME \
    --display-name="DISPLAY_NAME" \
    --project=PROJECT_ID
    
    # Grant permissions
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com \
      --role roles/container.defaultNodeServiceAccount
    
    • PROJECT_ID is the project ID where cluster-shield is running
  2. Grant Artifact Registry Reader role to the Service Account:

    gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
    --project="REGISTRY_PROJECT_ID" \
    --member=serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com \
    --role=roles/artifactregistry.reader
    
  3. Create the Node Pool:

    gcloud container node-pools create NODE_POOL_NAME \
    --service-account=SA_NAME@PROJECT_ID.iam.gserviceaccount.com \
    --cluster=CLUSTER_NAME
    

​ Cluster Shield automatically uses the attached service account.

Workload Identity Federation

Workload Identity Federation (WIF) provides secure, fine-grained authentication without direct service account keys.

Workload Identity Federation is enabled by default in GKE Autopilot clusters; no configuration required.

  1. Enable WIF:

    Applicable to standard clusters only.

    gcloud container clusters update CLUSTER_NAME \
    --location=LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog
    
  2. Configure the Node Pool:

    gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --workload-metadata=GKE_METADATA
    

Impersonate an IAM Service Account Using a Kubernetes Service Account

To impersonate an Identity and Access Management (IAM) Service Account Using a Kubernetes Service Account:

  1. Create a Kubernetes namespace:

    kubectl create namespace NAMESPACE
    
  2. Deploy Cluster Shield with Helm.

  3. Identify the Kubernetes Service Account:

    kubectl get deployment -n NAMESPACE CLUSTER-SHIELD-DEPLOYMENT \
    -o=jsonpath="{.spec.template.spec.serviceAccountName}"
    
  4. Bind Kubernetes Service Account to IAM Service Account:

    gcloud iam service-accounts add-iam-policy-binding IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com \
    --project \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]"
    
    • PROJECT_ID is the project ID where cluster-shield is running
    • NAMESPACE is the kubernetes namespace where cluster-shield is running
    • KSA_NAME is the Kubernetes Service Account (KSA) name used by cluster-shield and retrieved at previous step.
  5. Annotate Kubernetes Service Account.

    kubectl annotate serviceaccount KSA_NAME \
    --namespace NAMESPACE \
    iam.gke.io/gcp-service-account=IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com
    

​ Cluster Shield automatically starts using these credentials.

Authenticate Using Service Account Key

This authentication method relies on a user-managed key pair that can be used as a credential for a service account. Given that the credential is long-lived, it is the least secure option and we recommend you rely on the Docker Credential Helper instead.

To let Cluster Shield pull images by leveraging a Service Account Key:

  1. Use an existing service account, or create a new service account.:

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
    --description="DESCRIPTION" \
    --display-name="DISPLAY_NAME"
    
  2. If necessary, grant the specific role to the service account. For instance, for a private GAR, grant the Artifact Registry Reader role to all the necessary repositories. See Granting repository-specific roles.

    To grant a role to a single principal, run the following command:

    gcloud artifacts repositories add-iam-policy-binding REPOSITORY \
      --location=LOCATION \
      --member=serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com \
      --role=roles/artifactregistry.reader
    
    • REPOSITORY is the ID of the repository.
    • PRINCIPAL is the principal to add the binding for. Use the form user|group|serviceAccount:email or domain:domain.
    • Examples: user:test-user@gmail.com, group:admins@example.com, serviceAccount:test123@example.domain.com, or domain:example.domain.com.
    • ROLE is the role you want to grant.
    • LOCATION is the regional or multi-regional location of the repository.

    For GCR, see Grant IAM permissions.

  3. Create or retrieve the Service Account Key, following Create a service account key:

    Execute this command to create service account keys:

    gcloud iam service-accounts keys create KEY_FILE \
    --iam-account=SA_NAME@PROJECT_ID.iam.gserviceaccount.com
    
    • KEY_FILE: The path to a new output file for the private key, for example, ~/sa-private-key.json.
    • SA_NAME: The name of the service account to create a key for.
    • PROJECT_ID: Your Google Cloud project ID.
  4. Create a dockerconfigjson Secret in Kubernetes with the service account key. For GAR, follow Configuring an imagePullSecret.

    kubectl create secret docker-registry SECRET_NAME \
      --namespace=NAMESPACE \
      --docker-server=https://LOCATION-docker.pkg.dev \
      --docker-email=SERVICE-ACCOUNT-EMAIL \
      --docker-username=_json_key \
      --docker-password="$(cat KEY_FILE)"
    
    • LOCATION is the regional or multi-regional location of the repository.
    • SERVICE-ACCOUNT-EMAIL is the email address of the Compute Engine service account.
    • KEY-FILE is the name of your service account key file. For example key.json.

    For Google Container Registry, provide the correct value for --docker-server option as documented in JSON key file.

​5. Run Cluster Shield. Cluster Shield retrieves all dockerconfigjson (and legacy dockercfg) Secrets from all namespaces and uses them to authenticate to remote registries.

Advanced Troubleshooting

  • Check the Application Default Credentials (ADC) Token:

    gcloud auth application-default print-access-token
    
  • Check Node Pool Configuration:

    gcloud container node-pools describe NODE_POOL_NAME --cluster=CLUSTER_NAME
    
  • Validate Kubernetes Service Account Annotations:

    kubectl get serviceaccount KSA_NAME -n NAMESPACE -o yaml
    
  • Verify IAM Permissions:

    gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --format='table(bindings.role)' \
    --filter="bindings.members:serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com"
    

Learn More