Documentation

Google Cloud setup

Enable these products and roles before you paste a service account key. Agents, apps, and MCP servers deploy with Cloud Run in your project.

Paste a Google Cloud service account JSON key under Organization or Project Cloud accounts. Agents, apps, and MCP servers then run in your project on Cloud Run. Saving the key only proves it can sign in — APIs and roles must already be in place.

What gets deployed

All three workloads use Cloud Run. Agents also call Vertex AI at runtime.

WorkloadServiceGoogle products used
Agentgcp-cloud-runCloud Storage, Cloud Build, Artifact Registry, Cloud Run, Vertex AI (runtime)
Appgcp-cloud-runCloud Storage, Cloud Build, Artifact Registry, Cloud Run
MCPgcp-cloud-runSame as app

Three Google accounts, not one key

The JSON you paste is only the deployer. Cloud Build and Cloud Run still run as other accounts in the same project. Missing grants on those accounts is the usual “key works, deploy fails” case.

WhoLooks likeJob
1. Deployer (your JSON key)deployer@PROJECT.iam.gserviceaccount.comSubmit builds, create bucket/repo, create Cloud Run, set IAM
2. Cloud Build workerPROJECT_NUMBER@cloudbuild.gserviceaccount.comBuild the image and push to Artifact Registry
3. Cloud Run runtimePROJECT_NUMBER-compute@developer.gserviceaccount.comRuns the container. Agents need Vertex AI on this account

1. Turn on these APIs

Console → APIs & Services → Enable APIs, on the same project as project_id in the JSON. These are not enabled when you save the key.

Name in Google CloudAPIWhy
Cloud Runrun.googleapis.comCreate, update, delete, and scale the service
Cloud Buildcloudbuild.googleapis.comBuild the Docker image from uploaded source
Artifact Registryartifactregistry.googleapis.comStore the image (repo is created if missing)
Cloud Storagestorage.googleapis.comStaging bucket YOUR_PROJECT_cloudbuild
Cloud Logginglogging.googleapis.comBuild logs and runtime logs
IAMiam.googleapis.comactAs on the runtime account; set invoker
IAM Credentialsiamcredentials.googleapis.comMint identity tokens to call a private service
Cloud Resource Managercloudresourcemanager.googleapis.comProject-level IAM bindings
Service Usageserviceusage.googleapis.comNeeded so you can enable the other APIs
Compute Enginecompute.googleapis.comDefault Cloud Run runtime account
Vertex AIaiplatform.googleapis.comAgents (Gemini). Not required for a plain app or MCP
Cloud Monitoringmonitoring.googleapis.comOptional. Metrics in the console

Copy-paste (replace YOUR_PROJECT_ID):

gcloud services enable \
  run.googleapis.com \
  cloudbuild.googleapis.com \
  artifactregistry.googleapis.com \
  storage.googleapis.com \
  logging.googleapis.com \
  iam.googleapis.com \
  iamcredentials.googleapis.com \
  cloudresourcemanager.googleapis.com \
  serviceusage.googleapis.com \
  compute.googleapis.com \
  aiplatform.googleapis.com \
  monitoring.googleapis.com \
  --project=YOUR_PROJECT_ID

2. Roles on the key you paste

Use Artifact Registry Admin, not Writer — Writer cannot create the repository on first deploy. Include both roles/run.invoker (call the service) and roles/aiplatform.user (Vertex / Gemini). Invoker on the project lets the key call every Cloud Run service; you still bind it on each service for allUsers or other callers (step 5).

RolePurposeIf omitted
roles/run.adminCreate, update, delete Cloud Run; set IAM including invoker on the servicerun.services.create denied
roles/run.invokerCall Cloud Run (HTTPS). Needed on the key and on whoever hits the URL403 when opening or invoking the service
roles/cloudbuild.builds.editorStart Cloud Build jobscreate_build 403
roles/artifactregistry.adminGet and create the Docker repoRepository not found
roles/storage.adminCreate the staging bucket and upload sourcePermission denied on GCS bucket
roles/iam.serviceAccountUserLet Cloud Run use the Compute default account (actAs)actAs denied
roles/logging.viewerRead build and runtime logsLogs empty / 403
roles/monitoring.viewerCloud Run metricsMetrics page fails; deploy still works
roles/aiplatform.userVertex AI / Gemini. On the JSON key for Vertex APIs; also required on the runtime account (step 4)Agent cannot call Gemini (403 on aiplatform)
gcloud iam service-accounts create deployer \
  --display-name="Deployer" \
  --project=YOUR_PROJECT_ID

SA=deployer@YOUR_PROJECT_ID.iam.gserviceaccount.com
PROJECT=YOUR_PROJECT_ID

for ROLE in \
  roles/run.admin \
  roles/run.invoker \
  roles/cloudbuild.builds.editor \
  roles/artifactregistry.admin \
  roles/storage.admin \
  roles/iam.serviceAccountUser \
  roles/logging.viewer \
  roles/monitoring.viewer \
  roles/aiplatform.user
do
  gcloud projects add-iam-policy-binding $PROJECT \
    --member="serviceAccount:$SA" \
    --role="$ROLE"
done

3. Cloud Build worker (not your JSON key)

Granting Artifact Registry only on the JSON key does not let Cloud Build push. Grant these on PROJECT_NUMBER@cloudbuild.gserviceaccount.com.

Role on Cloud Build accountPurpose
roles/artifactregistry.writerPush the image to Artifact Registry
roles/storage.admin (or objectAdmin on the staging bucket)Read the uploaded source tarball
roles/logging.logWriterWrite build logs (CLOUD_LOGGING_ONLY)
PROJECT_NUMBER=$(gcloud projects describe YOUR_PROJECT_ID --format="value(projectNumber)")
CB=$PROJECT_NUMBER@cloudbuild.gserviceaccount.com

gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:$CB" --role="roles/artifactregistry.writer"

gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:$CB" --role="roles/storage.admin"

gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:$CB" --role="roles/logging.logWriter"

4. Cloud Run runtime account (agents)

Unless you set a custom runtime account, Cloud Run uses the Compute default. The deployer needs Service Account User on it. Agents call Vertex from inside the container, so the runtime account must have roles/aiplatform.user — granting it only on the JSON key is not enough.

RoleOn whomPurpose
roles/iam.serviceAccountUserDeployer, on the Compute default accountRequired to create the Cloud Run service (actAs)
roles/aiplatform.userCompute default (runtime)Gemini / Vertex from inside the agent container
PROJECT_NUMBER=$(gcloud projects describe YOUR_PROJECT_ID --format="value(projectNumber)")
COMPUTE=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:$COMPUTE" --role="roles/aiplatform.user"

gcloud iam service-accounts add-iam-policy-binding $COMPUTE \
  --member="serviceAccount:deployer@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/iam.serviceAccountUser" \
  --project=YOUR_PROJECT_ID

5. Who can call Cloud Run (roles/run.invoker)

Cloud Run is private by default. roles/run.admin creates the service; roles/run.invoker is who may send HTTP requests. Bind invoker on the service (or at project level on the JSON key, as in step 2).

MemberRoleWhen
allUsersroles/run.invoker on the Cloud Run servicePublic URL (no auth). Blocked if Domain Restricted Sharing is on
serviceAccount:deployer@PROJECT…roles/run.invoker on the service and/or the projectPrivate service: the key (or another caller) must be an invoker

Public (anyone on the internet):

gcloud run services add-iam-policy-binding SERVICE_NAME \
  --region=YOUR_REGION \
  --member="allUsers" \
  --role="roles/run.invoker" \
  --project=YOUR_PROJECT_ID

Private (only the deployer service account):

gcloud run services add-iam-policy-binding SERVICE_NAME \
  --region=YOUR_REGION \
  --member="serviceAccount:deployer@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/run.invoker" \
  --project=YOUR_PROJECT_ID

6. Download the JSON and paste it

Organization settings → Cloud accounts → Add credential → GCP service account. Paste the whole file. The key type must be service_account.

gcloud iam service-accounts keys create gcp-key.json \
  --iam-account=deployer@YOUR_PROJECT_ID.iam.gserviceaccount.com

If something still fails

What you seeCauseFix
Verified is green, deploy 403Verification only mints a token. It does not check APIs or rolesEnable the APIs and grant all three identities above
actAs denied on …-compute@…run.admin does not include using the default Compute accountService Account User on that account (step 4)
Artifact Registry repository not foundWriter cannot create the repoartifactregistry.admin + API enabled
Build succeeded, image missingCloud Build worker cannot pushartifactregistry.writer on the Cloud Build account
Cannot make the service public / allUsersOrg policy Domain Restricted SharingKeep the service private and grant roles/run.invoker to the caller SA, or relax that org policy
403 on the Cloud Run URLCaller is not an invokerroles/run.invoker on the service (step 5) and on the JSON key (step 2)
Agent 403 on Vertex / Geminiaiplatform.user missing on the runtime accountGrant roles/aiplatform.user on PROJECT_NUMBER-compute@… (step 4), not only on the JSON key