Database Migration
When the Built-in Integrations service is enabled, the Helm chart automatically handles database schema initialization and migrations. Automatic Migration Behavior:- Installation: Database schema is created automatically during initial chart installation
- Upgrades: Schema migrations run automatically before upgrading the Built-in Integrations service
- Execution: Runs as a Kubernetes Job with a 5-minute timeout and up to 5 retry attempts
- Database Readiness: When using internal PostgreSQL (
postgres.enabled: true), the migration waits for PostgreSQL to become available before proceeding
- Memory: 128Mi requested, 256Mi limit
- CPU: 100m requested, 300m limit
- Database connectivity issues (check
DB_HOST,DB_PORT,DB_PASSWORD) - Insufficient database permissions for the configured user
- Database not created when using external PostgreSQL (manual creation required)
- Internal PostgreSQL: Database created automatically (configured via
postgres.oauthDatabase) - External PostgreSQL: You must manually create the database specified in
envVars.POSTGRES_OAUTH_DB(defaults tooauth_db)
Core Configuration
Enable or disable the Built-in Integrations service deployment.Purpose: Controls whether the Built-in Integrations service and its associated resources (Deployment, Service, Ingress) are deployed to the cluster.When Enabled:
- Deploys Built-in Integrations service pods
- Creates Built-in Integrations ClusterIP service
- Optionally creates Ingress for external OAuth callbacks
- Automatically configures Rails application with Built-in Integrations service URL
- No Built-in Integrations service resources deployed
- Third-party integrations unavailable
- OAuth-related secrets still created but unused
Component name for the Built-in Integrations service.Purpose: Used for resource naming and labeling. Generally should not be changed.
Number of Built-in Integrations service pod replicas.High Availability: Multiple replicas ensure Built-in Integrations service availability during rolling updates and pod failures.Recommendations:
- Development:
1 - Production:
2or more for high availability - High-traffic:
3-5based on load
Container port for the Built-in Integrations service.Default:
8787Note: This is the internal container port. External access is configured via Ingress.Image Configuration
Container registry hostname for the Built-in Integrations service image.Default Behavior: If empty, falls back to
global.imageRegistry.Example:Built-in Integrations service image name.Default:
"proxy/crewai/crewai/crewai-oauth"Note: The image name includes the full path to the Built-in Integrations service container image.Built-in Integrations service image tag.Production Recommendation: Use specific version tags for reproducible deployments.Example:
Image pull policy for Built-in Integrations service.Valid Values:
"IfNotPresent"- Pull only if not cached locally"Always"- Always pull latest image"Never"- Never pull, use cached only
"IfNotPresent"Kubernetes secret name for Built-in Integrations service image registry authentication.Default Behavior: If empty, falls back to
image.pullSecret.Example:Service Configuration
Kubernetes service type for Built-in Integrations service.Default:
"ClusterIP"Recommendation: Keep as ClusterIP and use Ingress for external access.Valid Values:"ClusterIP"- Internal cluster access only (recommended)"LoadBalancer"- External LoadBalancer (not recommended, use Ingress instead)"NodePort"- Node port access (not recommended for production)
Service port for Built-in Integrations service.Default:
8787Note: This is the service port that other services use to communicate with the Built-in Integrations service internally.Target port on Built-in Integrations service pods.Default:
8787Note: Should match oauth.port.Resource Limits
CPU and memory resource requests and limits for Built-in Integrations service pods.Default Configuration:Tuning Guidelines:Low Traffic (< 100 users):Medium Traffic (100-500 users):High Traffic (500+ users):
Health Probes
Liveness probe configuration for Built-in Integrations service.Purpose: Kubernetes restarts the container if the liveness probe fails, recovering from deadlocks or hung processes.Default Configuration:Probe Details:
- Endpoint:
GET /healthon port8787 - Initial Delay: 30 seconds (allows service startup time)
- Check Interval: Every 30 seconds
- Timeout: 5 seconds per check
- Failure Threshold: 3 consecutive failures trigger restart
Readiness probe configuration for Built-in Integrations service.Purpose: Kubernetes removes the pod from service load balancing if the readiness probe fails, preventing traffic to unhealthy pods.Default Configuration:Probe Details:
- Endpoint:
GET /healthon port8787 - Initial Delay: 5 seconds
- Check Interval: Every 10 seconds
- Timeout: 5 seconds per check
- Failure Threshold: 3 consecutive failures mark pod as not ready
Node Placement
Node selector labels for Built-in Integrations service pod placement.Default:
{} (no node selector, schedule on any node)Use Cases:- Dedicated node pools for services
- GPU or specialized hardware requirements
- Cost optimization (spot/preemptible instances)
- Compliance requirements (data locality)
Ingress Configuration
The Built-in Integrations service requires external access for OAuth provider callbacks (redirects from Google, Microsoft, etc.). Ingress configuration provides secure HTTPS access to OAuth endpoints.How OAuth Routing Works
The web application’s Ingress is a catch-all on its hostname (path/), so every request to that hostname is sent to the web application unless a more specific route exists. The Built-in Integrations service is reachable only when its own Ingress (or HTTPRoute) adds that more specific route. If oauth.ingress.enabled is false, callbacks to the OAuth paths fall through to the web application and return its “Page not found” screen.
There are two supported routing models:
| Model | How it looks | When to use |
|---|---|---|
| Shared hostname + path prefix | OAuth is served under /oauthsvc on the same hostname as the web app (e.g. https://crewai.company.com/oauthsvc) | Default. Works with NGINX Ingress, which strips the /oauthsvc prefix before forwarding to the service. Also supported by the Gateway API HTTPRoute. |
| Dedicated hostname | OAuth is served at the root of its own hostname with path: "/" (e.g. https://oauth.company.com) | Required for AWS ALB and GKE native (GCE) Ingress, which cannot rewrite paths. |
The Built-in Integrations service serves its routes at the root path. In the shared-hostname model, the
/oauthsvc prefix must be stripped before the request reaches the service. The chart configures NGINX Ingress to perform this rewrite automatically. Ingress controllers that cannot rewrite paths (notably AWS ALB) cannot use the shared-hostname model — see oauth.ingress.className.Enable Ingress for Built-in Integrations service external access.Default:
falseRequired For: OAuth provider callbacks to work correctly.When Enabled:- Creates Ingress resource for OAuth endpoints
- OAuth providers can send callbacks to your domain
- Uses
oauth.ingress.hostor falls back toenvVars.APPLICATION_HOST
- OAuth callbacks will fail
- Third-party integrations cannot complete authentication flow
Ingress controller class name.Valid Values:
"nginx"- NGINX Ingress Controller"alb"- AWS Application Load Balancer"gce"- GKE native (GCE) Ingress Controller
"nginx"Choosing a controller for the OAuth route:- NGINX supports both routing models. With a shared hostname it automatically strips the
/oauthsvcprefix before forwarding to the service, so the defaultoauth.ingress.pathworks as-is. - AWS ALB cannot rewrite request paths. It forwards the path unchanged to the service, so the shared-hostname +
/oauthsvcmodel does not work — the service receives/oauthsvc/...and cannot match it. On ALB you must use a dedicated hostname withpath: "/"(see oauth.ingress.path). If you want to keep the shared hostname +/oauthsvc, front your services with the NGINX Ingress Controller instead of routing directly through ALB. - GKE native (GCE) does not support NGINX-style regex paths and cannot strip the
/oauthsvcprefix, so the shared-hostname model does not work here either. Use a dedicated hostname withpath: "/"andpathType: "Prefix". For GKE, the Gateway API (oauth.gateway) is also a supported alternative and does support a shared hostname with a path prefix.
On AWS ALB, each Ingress provisions its own load balancer by default, so the web and OAuth Ingresses get separate ALBs — point each hostname’s DNS at its own load balancer. This works without any extra configuration. If you prefer a single shared ALB (lower cost, one DNS target), add the same
alb.ingress.kubernetes.io/group.name annotation to both Ingresses (via web.ingress.annotations and oauth.ingress.annotations). Either way, each hostname must be covered by an ALB TLS certificate.Hostname for Built-in Integrations service external access.Default Behavior: If empty, falls back to Example with Shared Domain (using fallback):Path Configuration:By default, the OAuth service is exposed at the
envVars.APPLICATION_HOST.Format: Fully qualified domain name (FQDN)Important:- Must be configured in DNS to point to your Ingress controller
- Must match OAuth provider callback configuration
- Requires valid TLS certificate for HTTPS
/oauthsvc path prefix when sharing a hostname with the main application. When using NGINX Ingress Controller, the chart configures automatic path rewriting.For AWS ALB, GKE, or other ingress controllers that cannot rewrite request paths, use a separate hostname with path: "/". See path and pathType for details.Path for the OAuth service ingress rule.Default: AWS ALB example (dedicated hostname):By default this provisions two ALBs (one per Ingress); point each hostname’s DNS at its own load balancer. To consolidate both hostnames onto a single ALB, add the same
"/oauthsvc" (with regex pattern for NGINX)Purpose: Controls the URL path where the OAuth service is accessible. The default works with NGINX Ingress Controller which supports regex-based path rewriting.For GKE/ALB with Separate Hostname:When using GKE’s native ingress controller or AWS ALB with a dedicated OAuth hostname, set path: "/":alb.ingress.kubernetes.io/group.name annotation to both Ingresses.GKE’s native ingress controller does not support NGINX-style regex paths, and AWS ALB cannot rewrite request paths at all. For both, using a separate hostname with
path: "/" is required — the shared-hostname /oauthsvc model only works with NGINX.Kubernetes Ingress pathType for the OAuth service.Default:
"ImplementationSpecific" (for NGINX regex support)Valid Values:"ImplementationSpecific"- Default for NGINX with regex paths"Prefix"- Use with GKE/ALB whenpath: "/""Exact"- Exact path matching
Additional annotations for the OAuth Ingress resource.Purpose: Advanced Ingress controller configuration not covered by built-in settings.Example:
AWS ALB Configuration
AWS ALB scheme when using ALB Ingress controller.Valid Values:
"internet-facing"- Public internet access (required for OAuth)"internal"- VPC-internal only
"internet-facing"Note: OAuth callbacks require public internet access from OAuth providers.AWS ALB target type.Valid Values:
"ip"- Target pods by IP (recommended for most cases)"instance"- Target EC2 instances via NodePort
"ip"AWS ACM certificate ARN for HTTPS.Required: Yes (for ALB with HTTPS)Format: Example - Look up the ARN for a hostname:Example - Request a certificate covering both hostnames (DNS validation):
arn:aws:acm:region:account:certificate/idCertificate Coverage: The ACM certificate must be valid for the hostname the OAuth Ingress serves. Because AWS ALB requires a dedicated hostname for the OAuth service (e.g. oauth.company.com), that name must be on the certificate — either as a Subject Alternative Name or via a wildcard such as *.company.com. A single certificate that covers both the web and OAuth hostnames can be reused across both Ingresses (and is required if you consolidate them onto one ALB via group.name).Example - Reference an existing ACM certificate:If you omit
certificateArn, the AWS Load Balancer Controller attempts to auto-discover a matching ACM certificate by hostname. Setting it explicitly is recommended to avoid ambiguity when multiple certificates match.AWS ALB SSL policy.Default:
"ELBSecurityPolicy-TLS-1-2-2017-01"Other Options:"ELBSecurityPolicy-TLS13-1-2-2021-06"- TLS 1.3 and 1.2"ELBSecurityPolicy-FS-1-2-2019-08"- Forward secrecy
NGINX Ingress Configuration
Redirect HTTP to HTTPS automatically.Default:
trueRecommendation: Keep enabled for security. OAuth requires HTTPS.Maximum request body size.Default:
"10m" (10 megabytes)Purpose: Limits size of OAuth requests and responses.Enable CORS (Cross-Origin Resource Sharing).Default:
truePurpose: Allows Built-in Integrations service to be called from web application hosted on different subdomain.Allowed HTTP methods for CORS requests.Default:
"GET, POST, OPTIONS"Note: OAuth flows primarily use GET and POST methods.Allowed HTTP headers for CORS requests.Default: Standard headers for OAuth and API requests.
Allowed origins for CORS requests.Default:
"*" (allow all origins)Security Note: For production, consider restricting to specific domains:Allow credentials (cookies, authorization headers) in CORS requests.Default:
truePurpose: Required for OAuth cookie-based authentication.Enable TLS termination at NGINX.Default:
falseWhen Enabled: Requires TLS certificate in Kubernetes secret specified by oauth.ingress.nginx.tls.secretName.Example:Kubernetes secret name containing TLS certificate and key.Required When: Example - Create the secret from certificate files:Then reference it:Example - Issue the certificate automatically with cert-manager:When cert-manager is installed, annotate the Ingress with an issuer and cert-manager will create and renew the secret named in
oauth.ingress.nginx.tls.enabled: trueCertificate Coverage: The certificate must be valid for the hostname the OAuth Ingress serves (oauth.ingress.host, or envVars.APPLICATION_HOST when empty). For the shared-hostname model the web certificate already covers it; for a dedicated hostname (e.g. oauth.company.com) the certificate must include that name as a Subject Alternative Name, or be a wildcard such as *.company.com.Secret Format:secretName for you:Gateway API Configuration
Gateway API HTTPRoute configuration for OAuth service (alternative to Ingress).Gateway API vs Ingress: Gateway API is the modern successor to Ingress and is recommended for new deployments, especially on GKE. It provides standardized routing and better multi-tenancy support.
Enable Gateway API HTTPRoute for OAuth service.When Enabled:Example - Dedicated OAuth Hostname:Prerequisites:
- Creates an HTTPRoute resource for OAuth service
- Requires
gateway.enabled: trueat the global level - Routes traffic from Gateway listeners to OAuth service
- Automatically configures health check path to
/health
- No HTTPRoute created for OAuth service
- Use
oauth.ingress.*instead
- Gateway API CRDs installed in cluster
- Gateway resource exists (created via
gateway.create: trueor externally) - On GKE: Run
gcloud container clusters update CLUSTER --gateway-api=standard
On GKE, the chart automatically creates a HealthCheckPolicy that configures the load balancer’s health probes to use
/health as the check path. This prevents health check failures caused by Rails’ HostAuthorization middleware.Dedicated hostname for OAuth service (optional).Default Behavior: When empty, defaults to Example - Dedicated Hostname:
envVars.APPLICATION_HOST (shared hostname with web service).Purpose: Use a separate hostname for OAuth callbacks instead of sharing the web application’s hostname.When to Use Dedicated Hostname:- GKE or other ingress controllers that don’t support path rewriting
- Organizational preference for separate OAuth domain
- Security requirement for isolated OAuth traffic
Path prefix for OAuth service routes.Default: Example - Dedicated Hostname:
"/oauthsvc" (shared hostname mode)Purpose: Defines the URL path where OAuth endpoints are accessible.Values:"/oauthsvc"- Share hostname with web service (e.g.,https://crewai.company.com/oauthsvc)"/"- Use dedicated hostname (e.g.,https://oauth.company.com/)
pathPrefix is not "/", the chart automatically configures URLRewrite to strip the prefix when forwarding to the OAuth service.Example - Shared Hostname:The Gateway API HTTPRoute automatically configures path rewriting when using a non-root pathPrefix, eliminating the need for manual rewrite configuration.
Environment Configuration
Built-in Integrations service log level.Valid Values:
"debug", "info", "warn", "error"Default: "info"Recommendations:- Production:
"info"or"warn" - Development:
"debug"
Support Google Workspace identity by restricting Google apps to a specific domain.Purpose: When set, only users with email addresses from the specified Google Workspace domain can authenticate via Google Built-In integrations.Format: Domain name (e.g.,
company.com)Example:This setting only applies to Google Workspace integrations (Gmail, Calendar, Drive, etc.). See Google Workspace Integrations - Support Google Workspace Identity for more details.
OAuth Secrets Configuration
OAuth secrets are configured via theoauth.secrets values and are used to secure the Built-in Integrations service and enable third-party integrations. These secrets are separate from the main application secrets and are stored in a dedicated Kubernetes secret resource.
Auto-Generated Secrets
Secret key for signing OAuth session cookies.Auto-Generation: If not provided, automatically generated as a 64-character random alphanumeric string and persisted across upgrades.Purpose: Secures OAuth flow session data during the authentication process.Manual Generation:Leave Empty: To use auto-generated value (recommended).
Encryption key for OAuth tokens stored in the database.Auto-Generation: If not provided, automatically generated as a 64-character hexadecimal string and persisted across upgrades.Purpose: Encrypts sensitive OAuth tokens (access tokens, refresh tokens) at rest in the OAuth database.Format: 64-character hexadecimal string.Manual Generation:Leave Empty: To use auto-generated value (recommended).
Internal API key for authentication between the Built-in Integrations service and Rails application.Auto-Generation: If not provided, automatically generated as a 64-character random alphanumeric string and persisted across upgrades.Purpose: Enables secure service-to-service communication for OAuth operations.Important: This value is automatically duplicated as Leave Empty: To use auto-generated value (recommended).
CREWAI_OAUTH_API_KEY in the main application secrets for Rails to use.Manual Generation:OAuth Provider Credentials
OAuth provider credentials are optional and only required if you want to enable specific OAuth integrations. Each provider supports both provider-level credentials (shared across all products) and product-specific overrides.Google OAuth Provider
Google OAuth client ID used as default for all Google products.Purpose: Shared Google OAuth client ID. If product-specific client IDs are not provided, this value is used for all Google integrations (Gmail, Calendar, Drive, etc.).Obtain From: Google Cloud Console → APIs & Services → CredentialsExample:
Google OAuth client secret used as default for all Google products.Purpose: Shared Google OAuth client secret for all Google integrations.
Google Drive Picker API key for file picker functionality.Purpose: Enables Google Drive file picker UI in the application for selecting files from Google Drive.Obtain From: Google Cloud Console → APIs & Services → Credentials → Create Credentials → API KeyImportant: This is an API key (not OAuth credentials) specifically for the Google Picker API.Example:
Google Calendar-specific OAuth client ID.Override: Falls back to
oauth.secrets.google.clientId if not provided.Google Calendar-specific OAuth client secret.Override: Falls back to
oauth.secrets.google.clientSecret if not provided.Gmail-specific OAuth client ID.Override: Falls back to
oauth.secrets.google.clientId if not provided.Gmail-specific OAuth client secret.Override: Falls back to
oauth.secrets.google.clientSecret if not provided.Gmail Triggers Configuration
Gmail Triggers enable real-time email notifications using Google Cloud Pub/Sub. This requires a separate service account (not OAuth credentials) for Pub/Sub management.Google Cloud service account credentials for Gmail push notification triggers.Purpose: Authenticates with Google Cloud to manage Pub/Sub topics and subscriptions for Gmail push notifications.Required APIs: Gmail API, Cloud Pub/Sub API, Cloud Resource Manager APIRequired Role:
roles/pubsub.admin on the Google Cloud projectObtain From: Google Cloud Console → IAM & Admin → Service Accounts → Create Service Account → Create Key (JSON)Example:Google Drive-specific OAuth client ID.Override: Falls back to
oauth.secrets.google.clientId if not provided.Google Drive-specific OAuth client secret.Override: Falls back to
oauth.secrets.google.clientSecret if not provided.Google Contacts-specific OAuth client ID.Override: Falls back to
oauth.secrets.google.clientId if not provided.Google Contacts-specific OAuth client secret.Override: Falls back to
oauth.secrets.google.clientSecret if not provided.Google Sheets-specific OAuth client ID.Override: Falls back to
oauth.secrets.google.clientId if not provided.Google Sheets-specific OAuth client secret.Override: Falls back to
oauth.secrets.google.clientSecret if not provided.Google Slides-specific OAuth client ID.Override: Falls back to
oauth.secrets.google.clientId if not provided.Google Slides-specific OAuth client secret.Override: Falls back to
oauth.secrets.google.clientSecret if not provided.Google Docs-specific OAuth client ID.Override: Falls back to
oauth.secrets.google.clientId if not provided.Google Docs-specific OAuth client secret.Override: Falls back to
oauth.secrets.google.clientSecret if not provided.Microsoft OAuth Provider
Microsoft OAuth client ID used as default for all Microsoft products.Purpose: Shared Microsoft OAuth client ID. If product-specific client IDs are not provided, this value is used for all Microsoft integrations (Outlook, OneDrive, Teams, etc.).Obtain From: Microsoft Azure Portal → App registrationsExample:
Microsoft OAuth client secret used as default for all Microsoft products.Purpose: Shared Microsoft OAuth client secret for all Microsoft integrations.
Microsoft Azure AD tenant ID for single-tenant authentication.Purpose: When set, restricts authentication to users from the specified Azure AD tenant only (single-tenant mode). If not set, uses Microsoft’s
common endpoint allowing users from any Azure AD organization (multi-tenant mode).Obtain From: Microsoft Azure Portal → Microsoft Entra ID → Overview → Directory (tenant) IDExample:Outlook-specific OAuth client ID.Override: Falls back to
oauth.secrets.microsoft.clientId if not provided.Outlook-specific OAuth client secret.Override: Falls back to
oauth.secrets.microsoft.clientSecret if not provided.Outlook-specific Azure AD tenant ID.Override: Falls back to
oauth.secrets.microsoft.tenantId if not provided.OneDrive-specific OAuth client ID.Override: Falls back to
oauth.secrets.microsoft.clientId if not provided.OneDrive-specific OAuth client secret.Override: Falls back to
oauth.secrets.microsoft.clientSecret if not provided.OneDrive-specific Azure AD tenant ID.Override: Falls back to
oauth.secrets.microsoft.tenantId if not provided.Teams-specific OAuth client ID.Override: Falls back to
oauth.secrets.microsoft.clientId if not provided.Teams-specific OAuth client secret.Override: Falls back to
oauth.secrets.microsoft.clientSecret if not provided.Teams-specific Azure AD tenant ID.Override: Falls back to
oauth.secrets.microsoft.tenantId if not provided.SharePoint-specific OAuth client ID.Override: Falls back to
oauth.secrets.microsoft.clientId if not provided.SharePoint-specific OAuth client secret.Override: Falls back to
oauth.secrets.microsoft.clientSecret if not provided.SharePoint-specific Azure AD tenant ID.Override: Falls back to
oauth.secrets.microsoft.tenantId if not provided.Excel-specific OAuth client ID.Override: Falls back to
oauth.secrets.microsoft.clientId if not provided.Excel-specific OAuth client secret.Override: Falls back to
oauth.secrets.microsoft.clientSecret if not provided.Excel-specific Azure AD tenant ID.Override: Falls back to
oauth.secrets.microsoft.tenantId if not provided.Word-specific OAuth client ID.Override: Falls back to
oauth.secrets.microsoft.clientId if not provided.Word-specific OAuth client secret.Override: Falls back to
oauth.secrets.microsoft.clientSecret if not provided.Word-specific Azure AD tenant ID.Override: Falls back to
oauth.secrets.microsoft.tenantId if not provided.Other OAuth Providers
HubSpot OAuth client secret.
Notion OAuth client secret.
Salesforce OAuth consumer key (client ID) from an External Client App.Obtain From: Salesforce Setup → External Client App ManagerExample:
Salesforce OAuth consumer secret (client secret).
Related Configuration
OAuth Secrets: See Secrets Reference - Built-in Integrations Secrets for Built-in Integrations service secrets configuration including:OAUTH_COOKIE_SECRET- Session cookie signingOAUTH_DB_ENCRYPTION_KEY- Token encryptionOAUTH_INTERNAL_API_KEY- Service-to-service authentication- OAuth provider credentials (Google, Microsoft, HubSpot, Notion, Salesforce)
oauth_db). When using the internal PostgreSQL instance (postgres.enabled: true), the database is created automatically. When using an external database (postgres.enabled: false), you must manually create the database specified in envVars.POSTGRES_OAUTH_DB (defaults to oauth_db). See PostgreSQL Configuration and Environment Variables - POSTGRES_OAUTH_DB for configuration details.
Automatic URL Configuration: When Built-in Integrations service is enabled, the Rails application is automatically configured with CREWAI_OAUTH_API_BASE_URL pointing to the internal Built-in Integrations service URL. See Environment Variables - Built-in Integrations for details.