mtlynch
mtlynch

Reputation: 3553

docker push to gcr.io fails with "denied: Token exchange failed for project"

I've discovered a flow that works through GCP console but not through the gcloud CLI.

Minimal Repro

The following bash snippet creates a fresh GCP project and attempts to push an image to gcr.io, but fails with "access denied" even though the user is project owner:

gcloud auth login

PROJECT_ID="example-project-20181120"
gcloud projects create "$PROJECT_ID" --set-as-default
gcloud services enable containerregistry.googleapis.com
gcloud auth configure-docker --quiet

mkdir ~/docker-source && cd ~/docker-source
git clone https://github.com/mtlynch/docker-flask-upload-demo.git .

LOCAL_IMAGE_NAME="flask-demo-app"
GCR_IMAGE_PATH="gcr.io/${PROJECT_ID}/flask-demo-app"
docker build --tag "$LOCAL_IMAGE_NAME" .
docker tag "$LOCAL_IMAGE_NAME" "$GCR_IMAGE_PATH"
docker push "$GCR_IMAGE_PATH"

Result

The push refers to repository [gcr.io/example-project-20181120/flask-demo-app]
02205dbcdc63: Preparing
06ade19a43a0: Preparing
38d9ac54a7b9: Preparing
f83363c693c0: Preparing
b0d071df1063: Preparing
90d1009ce6fe: Waiting
denied: Token exchange failed for project 'example-project-20181120'. Access denied.

The system is Ubuntu 16.04 with the latest version of gcloud 225.0.0, as of this writing. The account I auth'ed with has role roles/owner.

Inconsistency with GCP Console

I notice that if I follow the same flow through GCP Console, I can docker push successfully:

  1. Create a new GCP project via GCP Console
  2. Create a service account with roles/owner via GCP Console
  3. Download JSON key for service account
  4. Enable container registry API via GCP Console
  5. gcloud auth activate-service-account --key-file key.json
  6. gcloud config set project $PROJECT_ID
  7. gcloud auth configure-docker --quiet
  8. docker tag "$LOCAL_IMAGE_NAME" "$GCR_IMAGE_PATH" && docker push "$GCR_IMAGE_PATH"

Result: Works as expected. Successfully pushes docker image to gcr.io.

Other attempts

I also tried using gcloud auth login as my @gmail.com account, then using that account to create a service account with gcloud, but that gets the same denied error:

SERVICE_ACCOUNT_NAME=test-service-account
gcloud iam service-accounts create "$SERVICE_ACCOUNT_NAME"
KEY_FILE="${HOME}/key.json"
gcloud iam service-accounts keys create "$KEY_FILE" \
  --iam-account "${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
  --member "serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role roles/owner
gcloud auth activate-service-account --key-file="${HOME}/key.json"

docker push "$GCR_IMAGE_PATH"

Result: denied: Token exchange failed for project 'example-project-20181120'. Access denied.

Upvotes: 3

Views: 3245

Answers (2)

Jai Narayan
Jai Narayan

Reputation: 89

In my case project IAM permission was the issue. Make sure proper permission given and also cloud resource/container registry API enabled. GCP Access Control

Upvotes: 0

Amit S
Amit S

Reputation: 72

I tried to reproduce the same error using bash snippet you provided, however it successfully built the ‘flask-demo-app’ container registry image for me. I used below steps to reproduce the issue:

Step 1: Use account which have ‘role: roles/owner’ and ‘role: roles/editor’

Step 2: Created bash script using your given snippet

Step 3: Added ‘gcloud auth activate-service-account --key-file skey.json’ in script to authenticate the account

Step 4: Run the bash script

Result : It created the ‘flask-demo-app’ container registry image

This leads me to believe that there might be an issue with your environment which is causing this error for you. To troubleshoot this you could try running your code on a different machine, a different network or even on the Cloud Shell.

Upvotes: 0

Related Questions