Skip to main content

Overview

This guide covers a complete, production-ready deployment of CrewAI Enterprise on Google Kubernetes Engine with the following stack:
  • GKE with Workload Identity (no static credentials)
  • Cloud SQL for PostgreSQL 16 via Cloud SQL Auth Proxy
  • GCS for object storage with IAM-signed URLs
  • Artifact Registry for crew container images
  • NGINX Ingress for TLS termination
  • WorkOS AuthKit for SSO
  • Wharf for OTLP trace collection (enabled by default)
  • Studio V2 (post-install configuration — no Helm values exist for this)
Work through each section in order. The Helm install cannot succeed until all infrastructure and auth prerequisites are complete.

Prerequisites Checklist

Complete every item before running helm install. GCP Infrastructure
  • GKE cluster running Kubernetes 1.28+ with Workload Identity enabled
  • gcloud CLI and kubectl configured against the target cluster
  • Helm 3.10+ installed
  • Required GCP APIs enabled (see below)
Cloud SQL
  • Cloud SQL for PostgreSQL 16 instance created
  • cloudsql.iam_authentication=on flag set on the instance
  • All four databases created: crewai_plus_production, crewai_plus_cable_production, crewai_plus_oauth_production, wharf
  • IAM database user created and privileges granted on all four databases
GCS
  • GCS bucket created for object storage
  • roles/storage.objectAdmin and roles/iam.serviceAccountTokenCreator granted to the GSA
Artifact Registry
  • Docker repository created with mutable tags (CrewAI overwrites tags)
  • roles/artifactregistry.writer granted to the GSA
  • Node pool compute SA granted roles/artifactregistry.reader
WorkOS
  • WorkOS application created with redirect URI https://<YOUR_DOMAIN>/auth/workos/callback
  • WorkOS API key, Client ID, and AuthKit domain noted
  • 32-character cookie password generated
DNS / TLS
  • DNS record pointing <YOUR_DOMAIN> to your NGINX ingress IP or reserved static IP
  • TLS certificate in a Kubernetes Secret named crewai-tls in the crewai namespace

Step 1: Enable Required GCP APIs


Step 2: Create the GCP Service Account

All CrewAI workloads share a single GSA mapped to the Kubernetes ServiceAccount via Workload Identity.
The Workload Identity binding in Step 4 references KSA_NAME. The chart creates a Kubernetes ServiceAccount named {release-name}-sa. This guide uses helm install crewai-platform, which produces crewai-platform-sa. If your release name differs, update KSA_NAME to match, or pin serviceAccount.name: crewai-platform-sa in your Helm values.

Step 3: Grant IAM Roles


Step 4: Bind Workload Identity

The [NAMESPACE/KSA_NAME] strings must exactly match the Kubernetes namespace and ServiceAccount name. A typo here causes a silent Workload Identity failure — pods start normally but all GCP API calls return 403.

Step 5: Create Cloud SQL Databases

Enable IAM authentication on the instance, then create all four required databases.
crewai_plus_oauth_production must be created explicitly. The chart default for POSTGRES_OAUTH_DB is oauth_db — if you do not override it in envVars, the OAuth service attempts to connect to a database that does not exist and fails silently at startup.Similarly, wharf must be pre-created. The Wharf trace collector expects this database to exist on startup.

Create the IAM Database User

Grant Privileges

Connect to the Cloud SQL instance and grant the IAM user access to all four databases. Replace GSA_NAME@GCP_PROJECT_ID.iam with your actual value (e.g., crewai-platform@my-project.iam):

Step 6: Create GCS Bucket


Step 7: Create Artifact Registry Repository

The repository must have mutable tags. CrewAI overwrites image tags on each crew deployment. Immutable tag repositories cause push failures.
The CREW_IMAGE_REGISTRY_OVERRIDE value is this prefix without the /crewai-enterprise suffix — the platform appends that automatically.

Step 8: Configure WorkOS

WORKOS_API_KEY and WORKOS_COOKIE_PASSWORD must be placed under envVars:, not secrets:. This is a known chart limitation. Values placed under secrets: are silently absent from pods — WorkOS authentication fails with no clear error message.After install, verify both variables are present in the pod:
  1. In the WorkOS Dashboard, navigate to Applications → Create Application (name it e.g., CrewAI Platform)
  2. Add redirect URI: https://<YOUR_DOMAIN>/auth/workos/callback
  3. Note your Client ID from the application main page
  4. Navigate to Developer → Domains and note your AuthKit domain
  5. Navigate to the main API Keys page and copy your API key (starts with sk_live_)
  6. Generate a cookie password (must be 32 characters or fewer):
The | cut -c -32 truncation is mandatory. WorkOS silently rejects cookie passwords longer than 32 characters — the install succeeds but all authentication attempts fail.

Complete values.yaml

Replace all <PLACEHOLDER> values before running helm install.
values.yaml

Step 9: Install

Watch pods come up:
All pods should reach Running within a few minutes. If any pod shows CrashLoopBackOff or Error, check logs before proceeding:

Step 10: Post-Install Annotations

After the first install, the crewai-crews namespace is created automatically. Annotate its default ServiceAccount so build pods can authenticate to Artifact Registry via Workload Identity:
Without this annotation, all crew image builds fail with a permission denied error when pushing to Artifact Registry.

Step 11: Required Post-Install Commands

Run these commands in order. Each must complete before proceeding to the next.
factory:grant_admin is the correct command for WorkOS SSO. This is distinct from Entra ID deployments, which use Azure App Roles instead.factory:grant_admin will fail if the user has not yet authenticated through WorkOS. Have the admin log in via the web UI first, then run the command.

Step 12: Enable Studio V2

Studio V2 cannot be configured in values.yaml. Adding studioV2.enabled, STUDIO_V2_ENABLED, or any similar key has no effect — Helm silently ignores unrecognized keys. Setup is always post-install via the UI and kubectl.

12a: Create the LLM Connection (UI)

  1. Navigate to Settings → LLM Connections
  2. Click New Connection
  3. Set the name to exactly studio-v2 (lowercase, no spaces — the install commands in 12c look up this name specifically)
  4. Select your LLM provider, enter the model name and API key
  5. Click Save

12b: Set as Default Connection (UI)

  1. Navigate to Settings → Crew Studio
  2. Under Default Connection, select studio-v2
  3. Click Save

12c: Run Install Commands

Run these in order. Each must complete successfully before running the next.

Step 13: Verify

Platform health

WorkOS authentication

Navigate to https://<YOUR_DOMAIN>. You should be redirected to the WorkOS AuthKit login page. If authentication fails, check that both WorkOS keys are present in the pod:
If either variable is missing, confirm they are under envVars: in values.yaml — not secrets: — and run helm upgrade.

WorkOS redirect URI

If you see a “redirect_uri_mismatch” error in the WorkOS dashboard, confirm the redirect URI in WorkOS exactly matches:

GCS signed URLs

If file uploads or downloads fail with SignedUrlUnavailable, confirm:
And that the GSA has roles/iam.serviceAccountTokenCreator.

Wharf trace collection

Studio V2

Both studio-assistant and studio-runner deployments should show Running.

Troubleshooting

WorkOS auth fails with no clear error

Both WORKOS_API_KEY and WORKOS_COOKIE_PASSWORD are absent from the pod. Move them from secrets: to envVars: and run helm upgrade. The password exceeds 32 characters. Regenerate: openssl rand -base64 32 | cut -c -32.

GCS signed URLs fail at runtime (install succeeds)

GCS_IAM_SIGNING is missing from envVars. This error only appears when users try to access uploaded files — the install itself succeeds, making it easy to miss. Add GCS_IAM_SIGNING: "true" and run helm upgrade.

OAuth service connects to wrong database

POSTGRES_OAUTH_DB is not set in envVars. The chart default oauth_db does not match the crewai_plus_oauth_production database you created. Add the override explicitly.

Cloud SQL connection refused on 127.0.0.1

The Cloud SQL Auth Proxy sidecar is not running. Check:
Verify cloudSqlProxy.instanceConnectionName matches the output of:

IAM database auth fails

Check that:
  1. cloudsql.iam_authentication=on flag is set on the instance
  2. DB_USER is the GSA email without .gserviceaccount.com (e.g., crewai-platform@my-project.iam)
  3. The IAM database user exists: gcloud sql users list --instance=$SQL_INSTANCE

502 errors from NGINX

web.enableSslFromPuma is not set to false. When NGINX handles TLS termination, Puma must not also attempt SSL. Set enableSslFromPuma: false in your web: block and run helm upgrade.

Crew image pushes fail (unauthorized)

The default ServiceAccount in crewai-crews is missing the Workload Identity annotation. Run:

studio:agent:install fails

The studio-v2 LLM Connection does not exist yet. Complete Steps 12a and 12b in the UI, then re-run the command.