> ## Documentation Index
> Fetch the complete documentation index at: https://enterprise-docs.crewai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CrewAI Built-in Integrations

> Configuration for the CrewAI Built-in Integrations service that handles third-party OAuth integrations.

The CrewAI Built-in Integrations service provides secure authentication and token management for third-party integrations including Gmail, Google Calendar, Microsoft Outlook, and other services. It operates as a separate microservice with its own database for storing encrypted OAuth tokens.

## 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

**Resource Requirements:**

The migration job uses modest resource allocations:

* **Memory:** 128Mi requested, 256Mi limit
* **CPU:** 100m requested, 300m limit

**Troubleshooting Migration Failures:**

If the migration job fails, check the job logs:

```bash theme={null}
# List migration jobs
kubectl get jobs -n <namespace> | grep oauth-migrate

# View logs from the most recent migration
kubectl logs -n <namespace> job/<release-name>-oauth-migrate-<revision>
```

Common failure causes:

* 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)

**Database Creation:**

* **Internal PostgreSQL:** Database created automatically (configured via `postgres.oauthDatabase`)
* **External PostgreSQL:** You must manually create the database specified in `envVars.POSTGRES_OAUTH_DB` (defaults to `oauth_db`)

## Core Configuration

<ParamField path="oauth.enabled" type="boolean" default="false">
  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

  **When Disabled:**

  * No Built-in Integrations service resources deployed
  * Third-party integrations unavailable
  * OAuth-related secrets still created but unused

  **Example:**

  ```yaml theme={null}
  oauth:
    enabled: true
  ```

  <Warning>
    When `oauth.enabled: true`, you must also configure external routing for the OAuth service. Without `oauth.gateway.enabled: true` (for Gateway API) or `oauth.ingress` (for Ingress), OAuth provider callbacks will silently fail. See the GCP Guide or AWS Guide for provider-specific routing examples.
  </Warning>
</ParamField>

<ParamField path="oauth.name" type="string" default="oauth">
  Component name for the Built-in Integrations service.

  **Purpose:** Used for resource naming and labeling. Generally should not be changed.
</ParamField>

<ParamField path="oauth.replicaCount" type="integer" default="2">
  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: `2` or more for high availability
  * High-traffic: `3-5` based on load

  **Example:**

  ```yaml theme={null}
  oauth:
    replicaCount: 3
  ```
</ParamField>

<ParamField path="oauth.port" type="integer" default="8787">
  Container port for the Built-in Integrations service.

  **Default:** `8787`

  **Note:** This is the internal container port. External access is configured via Ingress.
</ParamField>

## Image Configuration

<ParamField path="oauth.image.host" type="string" default="">
  Container registry hostname for the Built-in Integrations service image.

  **Default Behavior:** If empty, falls back to `global.imageRegistry`.

  **Example:**

  ```yaml theme={null}
  oauth:
    image:
      host: "images.crewai.com"
  ```
</ParamField>

<ParamField path="oauth.image.name" type="string" default="proxy/crewai/crewai/crewai-oauth">
  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.
</ParamField>

<ParamField path="oauth.image.tag" type="string" default="0.3.8">
  Built-in Integrations service image tag.

  **Production Recommendation:** Use specific version tags for reproducible deployments.

  **Example:**

  ```yaml theme={null}
  oauth:
    image:
      tag: "0.3.8"
  ```
</ParamField>

<ParamField path="oauth.image.pullPolicy" type="string" default="IfNotPresent">
  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

  **Default:** `"IfNotPresent"`
</ParamField>

<ParamField path="oauth.image.pullSecret" type="string" default="">
  Kubernetes secret name for Built-in Integrations service image registry authentication.

  **Default Behavior:** If empty, falls back to `image.pullSecret`.

  **Example:**

  ```yaml theme={null}
  oauth:
    image:
      pullSecret: "my-registry-secret"
  ```
</ParamField>

## Service Configuration

<ParamField path="oauth.service.type" type="string" default="ClusterIP">
  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)
</ParamField>

<ParamField path="oauth.service.port" type="integer" default="8787">
  Service port for Built-in Integrations service.

  **Default:** `8787`

  **Note:** This is the service port that other services use to communicate with the Built-in Integrations service internally.
</ParamField>

<ParamField path="oauth.service.targetPort" type="integer" default="8787">
  Target port on Built-in Integrations service pods.

  **Default:** `8787`

  **Note:** Should match `oauth.port`.
</ParamField>

## Resource Limits

<ParamField path="oauth.resources" type="object">
  CPU and memory resource requests and limits for Built-in Integrations service pods.

  **Default Configuration:**

  ```yaml theme={null}
  resources:
    limits:
      cpu: "500m"
      memory: "512Mi"
    requests:
      cpu: "250m"
      memory: "256Mi"
  ```

  **Tuning Guidelines:**

  **Low Traffic (\< 100 users):**

  ```yaml theme={null}
  resources:
    limits:
      cpu: "500m"
      memory: "512Mi"
    requests:
      cpu: "250m"
      memory: "256Mi"
  ```

  **Medium Traffic (100-500 users):**

  ```yaml theme={null}
  resources:
    limits:
      cpu: "1"
      memory: "1Gi"
    requests:
      cpu: "500m"
      memory: "512Mi"
  ```

  **High Traffic (500+ users):**

  ```yaml theme={null}
  resources:
    limits:
      cpu: "2"
      memory: "2Gi"
    requests:
      cpu: "1"
      memory: "1Gi"
  ```
</ParamField>

## Health Probes

<ParamField path="oauth.livenessProbe" type="object">
  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:**

  ```yaml theme={null}
  livenessProbe:
    initialDelaySeconds: 30
    periodSeconds: 30
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 3
  ```

  **Probe Details:**

  * **Endpoint:** `GET /health` on port `8787`
  * **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
</ParamField>

<ParamField path="oauth.readinessProbe" type="object">
  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:**

  ```yaml theme={null}
  readinessProbe:
    initialDelaySeconds: 5
    periodSeconds: 10
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 3
  ```

  **Probe Details:**

  * **Endpoint:** `GET /health` on port `8787`
  * **Initial Delay:** 5 seconds
  * **Check Interval:** Every 10 seconds
  * **Timeout:** 5 seconds per check
  * **Failure Threshold:** 3 consecutive failures mark pod as not ready
</ParamField>

## Node Placement

<ParamField path="oauth.nodeSelector" type="object" default="{}">
  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)

  **Example:**

  ```yaml theme={null}
  oauth:
    nodeSelector:
      workload: services
      tier: backend
  ```
</ParamField>

## 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](#gateway-api-configuration)) 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](#gateway-api-configuration) 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.                                                                                                      |

<Note>
  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](#param-oauth-ingress-classname).
</Note>

<Warning>
  For the shared-hostname model to work, the OAuth Ingress and the web Ingress must resolve to the **same hostname**. The web Ingress uses `web.ingress.host` directly, while the OAuth Ingress uses `oauth.ingress.host` and falls back to `envVars.APPLICATION_HOST` when empty. If `APPLICATION_HOST` is left at its default (`localhost`) and `oauth.ingress.host` is not set, the OAuth route will be created for `localhost` and never match your real hostname.
</Warning>

<ParamField path="oauth.ingress.enabled" type="boolean" default="false">
  Enable Ingress for Built-in Integrations service external access.

  **Default:** `false`

  **Required 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.host` or falls back to `envVars.APPLICATION_HOST`

  **When Disabled:**

  * OAuth callbacks will fail
  * Third-party integrations cannot complete authentication flow

  **Important:** OAuth callbacks require a publicly accessible HTTPS endpoint. If disabled, OAuth integrations will not function.
</ParamField>

<ParamField path="oauth.ingress.className" type="string" default="nginx">
  Ingress controller class name.

  **Valid Values:**

  * `"nginx"` - NGINX Ingress Controller
  * `"alb"` - AWS Application Load Balancer
  * `"gce"` - GKE native (GCE) Ingress Controller

  **Default:** `"nginx"`

  **Choosing a controller for the OAuth route:**

  * **NGINX** supports both routing models. With a shared hostname it automatically strips the `/oauthsvc` prefix before forwarding to the service, so the default `oauth.ingress.path` works as-is.
  * **AWS ALB** cannot rewrite request paths. It forwards the path unchanged to the service, so the shared-hostname + `/oauthsvc` model does **not** work — the service receives `/oauthsvc/...` and cannot match it. On ALB you must use a **dedicated hostname** with `path: "/"` (see [oauth.ingress.path](#param-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 `/oauthsvc` prefix, so the shared-hostname model does **not** work here either. Use a **dedicated hostname** with `path: "/"` and `pathType: "Prefix"`. For GKE, the [Gateway API](#gateway-api-configuration) (`oauth.gateway`) is also a supported alternative and does support a shared hostname with a path prefix.

  <Note>
    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.
  </Note>
</ParamField>

<ParamField path="oauth.ingress.host" type="string" default="">
  Hostname for Built-in Integrations service external access.

  **Default Behavior:** If empty, falls back to `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

  **Example with Dedicated Subdomain:**

  ```yaml theme={null}
  oauth:
    ingress:
      enabled: true
      host: "oauth.crewai.company.com"
  ```

  **Example with Shared Domain (using fallback):**

  ```yaml theme={null}
  oauth:
    ingress:
      enabled: true
      host: ""  # Falls back to APPLICATION_HOST
  ```

  **Path Configuration:**

  By default, the OAuth service is exposed at the `/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](#param-oauth-ingress-path) and [pathType](#param-oauth-ingress-pathtype) for details.
</ParamField>

<ParamField path="oauth.ingress.path" type="string" default="/oauthsvc">
  Path for the OAuth service ingress rule.

  **Default:** `"/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: "/"`:

  ```yaml theme={null}
  oauth:
    ingress:
      enabled: true
      className: gce
      host: "oauth.yourcompany.com"  # Separate hostname
      path: "/"
      pathType: "Prefix"
  ```

  **AWS ALB example (dedicated hostname):**

  ```yaml theme={null}
  web:
    ingress:
      enabled: true
      className: alb
      host: "crewai.company.com"
      path: "/"
      pathType: "Prefix"
      alb:
        certificateArn: "arn:aws:acm:us-west-2:123456789012:certificate/abc-def-123"

  oauth:
    enabled: true
    ingress:
      enabled: true
      className: alb
      host: "oauth.company.com"  # Dedicated hostname
      path: "/"
      pathType: "Prefix"
      alb:
        # Certificate must cover oauth.company.com (SAN entry or wildcard *.company.com)
        certificateArn: "arn:aws:acm:us-west-2:123456789012:certificate/abc-def-123"
  ```

  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 `alb.ingress.kubernetes.io/group.name` annotation to both Ingresses.

  <Note>
    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.
  </Note>
</ParamField>

<ParamField path="oauth.ingress.pathType" type="string" default="ImplementationSpecific">
  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 when `path: "/"`
  * `"Exact"` - Exact path matching

  **Example for GKE:**

  ```yaml theme={null}
  oauth:
    ingress:
      path: "/"
      pathType: "Prefix"
  ```
</ParamField>

<ParamField path="oauth.ingress.annotations" type="object" default="{}">
  Additional annotations for the OAuth Ingress resource.

  **Purpose:** Advanced Ingress controller configuration not covered by built-in settings.

  **Example:**

  ```yaml theme={null}
  oauth:
    ingress:
      annotations:
        cert-manager.io/cluster-issuer: "letsencrypt-prod"
        nginx.ingress.kubernetes.io/rate-limit: "100"
  ```
</ParamField>

### AWS ALB Configuration

<ParamField path="oauth.ingress.alb.scheme" type="string" default="internet-facing">
  AWS ALB scheme when using ALB Ingress controller.

  **Valid Values:**

  * `"internet-facing"` - Public internet access (required for OAuth)
  * `"internal"` - VPC-internal only

  **Default:** `"internet-facing"`

  **Note:** OAuth callbacks require public internet access from OAuth providers.
</ParamField>

<ParamField path="oauth.ingress.alb.targetType" type="string" default="ip">
  AWS ALB target type.

  **Valid Values:**

  * `"ip"` - Target pods by IP (recommended for most cases)
  * `"instance"` - Target EC2 instances via NodePort

  **Default:** `"ip"`
</ParamField>

<ParamField path="oauth.ingress.alb.certificateArn" type="string" default="">
  AWS ACM certificate ARN for HTTPS.

  **Required:** Yes (for ALB with HTTPS)

  **Format:** `arn:aws:acm:region:account:certificate/id`

  **Certificate Coverage:** The ACM certificate must be valid for the hostname the OAuth Ingress serves. Because AWS ALB requires a [dedicated hostname](#param-oauth-ingress-classname) 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:**

  ```yaml theme={null}
  oauth:
    ingress:
      enabled: true
      className: alb
      host: "oauth.company.com"
      alb:
        certificateArn: "arn:aws:acm:us-west-2:123456789012:certificate/abc-def-123"
  ```

  **Example - Look up the ARN for a hostname:**

  ```bash theme={null}
  aws acm list-certificates \
    --query "CertificateSummaryList[?DomainName=='oauth.company.com'].CertificateArn" \
    --output text
  ```

  **Example - Request a certificate covering both hostnames (DNS validation):**

  ```bash theme={null}
  aws acm request-certificate \
    --domain-name crewai.company.com \
    --subject-alternative-names oauth.company.com \
    --validation-method DNS
  ```

  <Note>
    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.
  </Note>
</ParamField>

<ParamField path="oauth.ingress.alb.sslPolicy" type="string" default="ELBSecurityPolicy-TLS-1-2-2017-01">
  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

  **Recommendation:** Use TLS 1.2 minimum for security.
</ParamField>

### NGINX Ingress Configuration

<ParamField path="oauth.ingress.nginx.sslRedirect" type="boolean" default="true">
  Redirect HTTP to HTTPS automatically.

  **Default:** `true`

  **Recommendation:** Keep enabled for security. OAuth requires HTTPS.
</ParamField>

<ParamField path="oauth.ingress.nginx.proxyBodySize" type="string" default="10m">
  Maximum request body size.

  **Default:** `"10m"` (10 megabytes)

  **Purpose:** Limits size of OAuth requests and responses.
</ParamField>

<ParamField path="oauth.ingress.nginx.enableCors" type="boolean" default="true">
  Enable CORS (Cross-Origin Resource Sharing).

  **Default:** `true`

  **Purpose:** Allows Built-in Integrations service to be called from web application hosted on different subdomain.
</ParamField>

<ParamField path="oauth.ingress.nginx.corsAllowMethods" type="string" default="GET, POST, OPTIONS">
  Allowed HTTP methods for CORS requests.

  **Default:** `"GET, POST, OPTIONS"`

  **Note:** OAuth flows primarily use GET and POST methods.
</ParamField>

<ParamField path="oauth.ingress.nginx.corsAllowHeaders" type="string" default="DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization">
  Allowed HTTP headers for CORS requests.

  **Default:** Standard headers for OAuth and API requests.
</ParamField>

<ParamField path="oauth.ingress.nginx.corsAllowOrigin" type="string" default="*">
  Allowed origins for CORS requests.

  **Default:** `"*"` (allow all origins)

  **Security Note:** For production, consider restricting to specific domains:

  ```yaml theme={null}
  oauth:
    ingress:
      nginx:
        corsAllowOrigin: "https://crewai.company.com"
  ```
</ParamField>

<ParamField path="oauth.ingress.nginx.corsAllowCredentials" type="boolean" default="true">
  Allow credentials (cookies, authorization headers) in CORS requests.

  **Default:** `true`

  **Purpose:** Required for OAuth cookie-based authentication.
</ParamField>

<ParamField path="oauth.ingress.nginx.tls.enabled" type="boolean" default="false">
  Enable TLS termination at NGINX.

  **Default:** `false`

  **When Enabled:** Requires TLS certificate in Kubernetes secret specified by `oauth.ingress.nginx.tls.secretName`.

  **Example:**

  ```yaml theme={null}
  oauth:
    ingress:
      nginx:
        tls:
          enabled: true
          secretName: "oauth-tls-cert"
  ```
</ParamField>

<ParamField path="oauth.ingress.nginx.tls.secretName" type="string" default="">
  Kubernetes secret name containing TLS certificate and key.

  **Required When:** `oauth.ingress.nginx.tls.enabled: true`

  **Certificate 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:**

  ```yaml theme={null}
  apiVersion: v1
  kind: Secret
  metadata:
    name: oauth-tls-cert
  type: kubernetes.io/tls
  data:
    tls.crt: <base64-encoded-certificate>
    tls.key: <base64-encoded-private-key>
  ```

  **Example - Create the secret from certificate files:**

  ```bash theme={null}
  kubectl create secret tls oauth-tls-cert \
    --cert=oauth.company.com.crt \
    --key=oauth.company.com.key \
    --namespace <release-namespace>
  ```

  Then reference it:

  ```yaml theme={null}
  oauth:
    ingress:
      enabled: true
      className: nginx
      host: "oauth.company.com"
      nginx:
        tls:
          enabled: true
          secretName: "oauth-tls-cert"
  ```

  **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 `secretName` for you:

  ```yaml theme={null}
  oauth:
    ingress:
      enabled: true
      className: nginx
      host: "oauth.company.com"
      annotations:
        cert-manager.io/cluster-issuer: "letsencrypt-prod"
      nginx:
        tls:
          enabled: true
          secretName: "oauth-tls-cert"
  ```
</ParamField>

## Gateway API Configuration

Gateway API HTTPRoute configuration for OAuth service (alternative to Ingress).

<Note>
  **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.
</Note>

<ParamField path="oauth.gateway.enabled" type="boolean" default="false">
  Enable Gateway API HTTPRoute for OAuth service.

  **When Enabled:**

  * Creates an HTTPRoute resource for OAuth service
  * Requires `gateway.enabled: true` at the global level
  * Routes traffic from Gateway listeners to OAuth service
  * Automatically configures health check path to `/health`

  **When Disabled:**

  * No HTTPRoute created for OAuth service
  * Use `oauth.ingress.*` instead

  **Example - Shared Hostname with Path Prefix:**

  ```yaml theme={null}
  gateway:
    enabled: true
    gatewayClassName: gke-l7-global-external-managed

  oauth:
    enabled: true
    gateway:
      enabled: true
      pathPrefix: /oauthsvc  # OAuth at https://crewai.company.com/oauthsvc
  ```

  **Example - Dedicated OAuth Hostname:**

  ```yaml theme={null}
  gateway:
    enabled: true
    gatewayClassName: gke-l7-global-external-managed

  oauth:
    enabled: true
    gateway:
      enabled: true
      hostname: oauth.company.com
      pathPrefix: /  # OAuth at https://oauth.company.com/
  ```

  **Prerequisites:**

  * Gateway API CRDs installed in cluster
  * Gateway resource exists (created via `gateway.create: true` or externally)
  * On GKE: Run `gcloud container clusters update CLUSTER --gateway-api=standard`

  <Note>
    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.
  </Note>
</ParamField>

<ParamField path="oauth.gateway.hostname" type="string" default="">
  Dedicated hostname for OAuth service (optional).

  **Default Behavior:** When empty, defaults to `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

  **Example - Shared Hostname (Default):**

  ```yaml theme={null}
  envVars:
    APPLICATION_HOST: crewai.company.com

  oauth:
    gateway:
      enabled: true
      hostname: ""  # Uses crewai.company.com
      pathPrefix: /oauthsvc  # OAuth at /oauthsvc path
  ```

  **Example - Dedicated Hostname:**

  ```yaml theme={null}
  oauth:
    gateway:
      enabled: true
      hostname: oauth.company.com
      pathPrefix: /  # OAuth at root path
  ```

  <Warning>
    When using a dedicated hostname:

    1. Add the hostname to your Gateway's TLS certificate or certificate map
    2. Configure DNS to point to the same Gateway IP address
    3. Update OAuth provider callback URLs to use the dedicated hostname
  </Warning>
</ParamField>

<ParamField path="oauth.gateway.pathPrefix" type="string" default="/oauthsvc">
  Path prefix for OAuth service routes.

  **Default:** `"/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/`)

  **Path Rewriting:** When `pathPrefix` is not `"/"`, the chart automatically configures URLRewrite to strip the prefix when forwarding to the OAuth service.

  **Example - Shared Hostname:**

  ```yaml theme={null}
  oauth:
    gateway:
      enabled: true
      pathPrefix: /oauthsvc

  # OAuth callback URLs:
  # https://crewai.company.com/oauthsvc/v1/auth/google/callback
  # https://crewai.company.com/oauthsvc/v1/auth/microsoft/callback
  ```

  **Example - Dedicated Hostname:**

  ```yaml theme={null}
  oauth:
    gateway:
      enabled: true
      hostname: oauth.company.com
      pathPrefix: /

  # OAuth callback URLs:
  # https://oauth.company.com/v1/auth/google/callback
  # https://oauth.company.com/v1/auth/microsoft/callback
  ```

  <Note>
    The Gateway API HTTPRoute automatically configures path rewriting when using a non-root pathPrefix, eliminating the need for manual rewrite configuration.
  </Note>
</ParamField>

**Complete Example - Shared Hostname:**

```yaml theme={null}
# Global Gateway configuration
gateway:
  enabled: true
  create: true
  gatewayClassName: gke-l7-global-external-managed
  annotations:
    networking.gke.io/certmap: crewai-cert-map
  listeners:
    - name: https
      protocol: HTTPS
      port: 443

# Web service
web:
  gateway:
    enabled: true
    hostnames:
      - crewai.company.com

# OAuth service - shared hostname with path prefix
oauth:
  enabled: true
  gateway:
    enabled: true
    pathPrefix: /oauthsvc
```

**Complete Example - Dedicated Hostname:**

```yaml theme={null}
# Global Gateway configuration
gateway:
  enabled: true
  create: true
  gatewayClassName: gke-l7-global-external-managed
  annotations:
    networking.gke.io/certmap: crewai-cert-map
  listeners:
    - name: https
      protocol: HTTPS
      port: 443

# Web service
web:
  gateway:
    enabled: true
    hostnames:
      - crewai.company.com

# OAuth service - dedicated hostname
oauth:
  enabled: true
  gateway:
    enabled: true
    hostname: oauth.company.com
    pathPrefix: /
```

**See Also:** [Gateway API Configuration](/reference/chart-values/gateway) for Gateway resource configuration.

## Environment Configuration

<ParamField path="oauth.config.logLevel" type="string" default="info">
  Built-in Integrations service log level.

  **Valid Values:** `"debug"`, `"info"`, `"warn"`, `"error"`

  **Default:** `"info"`

  **Recommendations:**

  * Production: `"info"` or `"warn"`
  * Development: `"debug"`

  **Example:**

  ```yaml theme={null}
  oauth:
    config:
      logLevel: "debug"
  ```
</ParamField>

<ParamField path="oauth.config.googleWorkspaceDomain" type="string" default="">
  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:**

  ```yaml theme={null}
  oauth:
    config:
      googleWorkspaceDomain: "company.com"
  ```

  <Note>
    This setting only applies to Google Workspace integrations (Gmail, Calendar, Drive, etc.). See [Google Workspace Integrations - Support Google Workspace Identity](/features/google-integrations#support-google-workspace-identity) for more details.
  </Note>
</ParamField>

## OAuth Secrets Configuration

OAuth secrets are configured via the `oauth.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

<ParamField path="oauth.secrets.cookieSecret" type="string" default="">
  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:**

  ```bash theme={null}
  openssl rand -base64 48 | tr -d '\n'
  ```

  **ArgoCD Users:** Must be set explicitly — see [ArgoCD Deployment Guide](/configuration/argocd).

  **Leave Empty:** To use auto-generated value (recommended for non-ArgoCD deployments).
</ParamField>

<ParamField path="oauth.secrets.dbEncryptionKey" type="string" default="">
  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:**

  ```bash theme={null}
  openssl rand -hex 32
  ```

  **ArgoCD Users:** Must be set explicitly — see [ArgoCD Deployment Guide](/configuration/argocd).

  **Leave Empty:** To use auto-generated value (recommended for non-ArgoCD deployments).
</ParamField>

<ParamField path="oauth.secrets.internalApiKey" type="string" default="">
  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 `CREWAI_OAUTH_API_KEY` in the main application secrets for Rails to use.

  **Manual Generation:**

  ```bash theme={null}
  openssl rand -base64 48 | tr -d '\n'
  ```

  **ArgoCD Users:** Must be set explicitly — see [ArgoCD Deployment Guide](/configuration/argocd).

  **Leave Empty:** To use auto-generated value (recommended for non-ArgoCD deployments).
</ParamField>

### 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

<ParamField path="oauth.secrets.google.clientId" type="string" default="">
  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](https://console.cloud.google.com/) → APIs & Services → Credentials

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      google:
        clientId: "123456789-abcdefg.apps.googleusercontent.com"
        clientSecret: "GOCSPX-abc123..."
  ```
</ParamField>

<ParamField path="oauth.secrets.google.clientSecret" type="string" default="">
  Google OAuth client secret used as default for all Google products.

  **Purpose:** Shared Google OAuth client secret for all Google integrations.
</ParamField>

<ParamField path="oauth.secrets.google.drivePickerKey" type="string" default="">
  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](https://console.cloud.google.com/) → APIs & Services → Credentials → Create Credentials → API Key

  **Important:** This is an API key (not OAuth credentials) specifically for the Google Picker API.

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      google:
        clientId: "123456789-abcdefg.apps.googleusercontent.com"
        clientSecret: "GOCSPX-abc123..."
        drivePickerKey: "AIzaSyAbc123def456..."
  ```
</ParamField>

**Product-Specific Google OAuth Overrides:**

You can override the provider-level credentials for specific Google products. If not provided, the provider-level credentials are used.

<ParamField path="oauth.secrets.google.calendar.clientId" type="string" default="">
  Google Calendar-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.google.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.calendar.clientSecret" type="string" default="">
  Google Calendar-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.google.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.gmail.clientId" type="string" default="">
  Gmail-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.google.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.gmail.clientSecret" type="string" default="">
  Gmail-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.google.clientSecret` if not provided.
</ParamField>

#### 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.

<ParamField path="oauth.secrets.google.gmail.triggers.serviceAccountCredentials" type="object" default="{}">
  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 API

  **Required Role:** `roles/pubsub.admin` on the Google Cloud project

  **Obtain From:** Google Cloud Console → IAM & Admin → Service Accounts → Create Service Account → Create Key (JSON)

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      google:
        gmail:
          triggers:
            serviceAccountCredentials:
              type: service_account
              project_id: your-project
              private_key_id: abc123...
              private_key: |
                -----BEGIN PRIVATE KEY-----
                MIIEvgIBADANBgkqhkiG9w0BAQEFAASC...
                -----END PRIVATE KEY-----
              client_email: gmail-triggers@your-project.iam.gserviceaccount.com
              client_id: "123456789"
              auth_uri: https://accounts.google.com/o/oauth2/auth
              token_uri: https://oauth2.googleapis.com/token
              auth_provider_x509_cert_url: https://www.googleapis.com/oauth2/v1/certs
              client_x509_cert_url: https://www.googleapis.com/robot/v1/metadata/x509/...
              universe_domain: googleapis.com
  ```
</ParamField>

<ParamField path="oauth.secrets.google.drive.clientId" type="string" default="">
  Google Drive-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.google.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.drive.clientSecret" type="string" default="">
  Google Drive-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.google.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.contacts.clientId" type="string" default="">
  Google Contacts-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.google.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.contacts.clientSecret" type="string" default="">
  Google Contacts-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.google.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.sheets.clientId" type="string" default="">
  Google Sheets-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.google.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.sheets.clientSecret" type="string" default="">
  Google Sheets-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.google.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.slides.clientId" type="string" default="">
  Google Slides-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.google.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.slides.clientSecret" type="string" default="">
  Google Slides-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.google.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.docs.clientId" type="string" default="">
  Google Docs-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.google.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.google.docs.clientSecret" type="string" default="">
  Google Docs-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.google.clientSecret` if not provided.
</ParamField>

#### Microsoft OAuth Provider

<ParamField path="oauth.secrets.microsoft.clientId" type="string" default="">
  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](https://portal.azure.com/) → App registrations

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      microsoft:
        clientId: "12345678-1234-1234-1234-123456789abc"
        clientSecret: "abc123~def456..."
  ```
</ParamField>

<ParamField path="oauth.secrets.microsoft.clientSecret" type="string" default="">
  Microsoft OAuth client secret used as default for all Microsoft products.

  **Purpose:** Shared Microsoft OAuth client secret for all Microsoft integrations.
</ParamField>

<ParamField path="oauth.secrets.microsoft.tenantId" type="string" default="">
  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](https://portal.azure.com/) → Microsoft Entra ID → Overview → Directory (tenant) ID

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      microsoft:
        clientId: "12345678-1234-1234-1234-123456789abc"
        clientSecret: "abc123~def456..."
        tenantId: "87654321-4321-4321-4321-cba987654321"
  ```
</ParamField>

**Product-Specific Microsoft OAuth Overrides:**

<ParamField path="oauth.secrets.microsoft.outlook.clientId" type="string" default="">
  Outlook-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.microsoft.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.outlook.clientSecret" type="string" default="">
  Outlook-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.microsoft.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.outlook.tenantId" type="string" default="">
  Outlook-specific Azure AD tenant ID.

  **Override:** Falls back to `oauth.secrets.microsoft.tenantId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.onedrive.clientId" type="string" default="">
  OneDrive-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.microsoft.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.onedrive.clientSecret" type="string" default="">
  OneDrive-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.microsoft.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.onedrive.tenantId" type="string" default="">
  OneDrive-specific Azure AD tenant ID.

  **Override:** Falls back to `oauth.secrets.microsoft.tenantId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.teams.clientId" type="string" default="">
  Teams-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.microsoft.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.teams.clientSecret" type="string" default="">
  Teams-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.microsoft.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.teams.tenantId" type="string" default="">
  Teams-specific Azure AD tenant ID.

  **Override:** Falls back to `oauth.secrets.microsoft.tenantId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.sharepoint.clientId" type="string" default="">
  SharePoint-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.microsoft.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.sharepoint.clientSecret" type="string" default="">
  SharePoint-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.microsoft.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.sharepoint.tenantId" type="string" default="">
  SharePoint-specific Azure AD tenant ID.

  **Override:** Falls back to `oauth.secrets.microsoft.tenantId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.excel.clientId" type="string" default="">
  Excel-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.microsoft.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.excel.clientSecret" type="string" default="">
  Excel-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.microsoft.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.excel.tenantId" type="string" default="">
  Excel-specific Azure AD tenant ID.

  **Override:** Falls back to `oauth.secrets.microsoft.tenantId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.word.clientId" type="string" default="">
  Word-specific OAuth client ID.

  **Override:** Falls back to `oauth.secrets.microsoft.clientId` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.word.clientSecret" type="string" default="">
  Word-specific OAuth client secret.

  **Override:** Falls back to `oauth.secrets.microsoft.clientSecret` if not provided.
</ParamField>

<ParamField path="oauth.secrets.microsoft.word.tenantId" type="string" default="">
  Word-specific Azure AD tenant ID.

  **Override:** Falls back to `oauth.secrets.microsoft.tenantId` if not provided.
</ParamField>

#### Other OAuth Providers

<ParamField path="oauth.secrets.hubspot.clientId" type="string" default="">
  HubSpot OAuth client ID.

  **Obtain From:** [HubSpot Developer Portal](https://developers.hubspot.com/)

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      hubspot:
        clientId: "12345678-abcd-1234-abcd-123456789abc"
        clientSecret: "abc123def456..."
  ```
</ParamField>

<ParamField path="oauth.secrets.hubspot.clientSecret" type="string" default="">
  HubSpot OAuth client secret.
</ParamField>

<ParamField path="oauth.secrets.notion.clientId" type="string" default="">
  Notion OAuth client ID.

  **Obtain From:** [Notion Integrations](https://www.notion.so/my-integrations)

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      notion:
        clientId: "secret_abc123def456..."
        clientSecret: "secret_xyz789..."
  ```
</ParamField>

<ParamField path="oauth.secrets.notion.clientSecret" type="string" default="">
  Notion OAuth client secret.
</ParamField>

<ParamField path="oauth.secrets.salesforce.clientId" type="string" default="">
  Salesforce OAuth consumer key (client ID) from an External Client App.

  **Obtain From:** [Salesforce Setup → External Client App Manager](https://help.salesforce.com/s/articleView?id=sf.connected_app_create.htm)

  **Example:**

  ```yaml theme={null}
  oauth:
    secrets:
      salesforce:
        clientId: "3MVG9..."
        clientSecret: "ABCDEF123456..."
  ```
</ParamField>

<ParamField path="oauth.secrets.salesforce.clientSecret" type="string" default="">
  Salesforce OAuth consumer secret (client secret).
</ParamField>

***

## Related Configuration

**OAuth Secrets:** See [Secrets Reference - Built-in Integrations Secrets](/reference/chart-values/secrets#built-in-integrations-secrets) for Built-in Integrations service secrets configuration including:

* `OAUTH_COOKIE_SECRET` - Session cookie signing
* `OAUTH_DB_ENCRYPTION_KEY` - Token encryption
* `OAUTH_INTERNAL_API_KEY` - Service-to-service authentication
* OAuth provider credentials (Google, Microsoft, HubSpot, Notion, Salesforce)

**OAuth Database:** The Built-in Integrations service uses a separate database (`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](/reference/chart-values/postgres) and [Environment Variables - POSTGRES\_OAUTH\_DB](/reference/chart-values/environment-variables#param-env-vars-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](/reference/chart-values/environment-variables#crewai-built-in-integration) for details.
