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

# Web Application Configuration

> Configuration for the CrewAI Platform web application (Rails-based frontend and API).

<ParamField path="web.name" type="string" default="web">
  Name identifier for web component. Used in labels and resource names.
</ParamField>

<ParamField path="web.useHttps" type="boolean" default="true">
  Enable HTTPS protocol for external access.

  **When Enabled:**

  * Application is accessed via HTTPS URL
  * Must be set to `true` when using `web.enableSslFromPuma: true`
  * Required for proper protocol detection in URLs

  **When to Disable:**

  * Ingress handles TLS termination and application accessed via HTTP
  * Internal cluster-only access without encryption
</ParamField>

<ParamField path="web.enableSslFromPuma" type="boolean" default="true">
  Enable SSL/TLS at the application level (Puma web server).

  **When Enabled:**

  * Puma serves HTTPS directly with TLS certificates
  * Automatically sets `APPLICATION_INTERNAL_URL` to use `https://`
  * Automatically sets NGINX `backend-protocol` to `HTTPS`
  * Requires SSL certificate configuration (via `web.tls.autoGenerate` or `secrets.SSL_*`)

  **When to Disable:**

  * Ingress or load balancer handles TLS termination
  * Application serves HTTP only
  * Using external TLS proxy

  **Note:** This is different from `web.useHttps` which controls the external protocol, while `enableSslFromPuma` controls whether Puma itself handles TLS encryption.
</ParamField>

<ParamField path="web.port" type="integer" default="443">
  Port where the web application listens.

  **Default Behavior:**

  * `443` when `web.enableSslFromPuma: true` (HTTPS)
  * Typically `80` or `3000` when TLS is disabled

  **Note:** This is the container port. Service port is auto-configured based on this value and ingress settings.
</ParamField>

<ParamField path="web.replicaCount" type="integer" default="1">
  Number of web application replicas.

  **High Availability Recommendations:**

  * **Development:** 1 replica
  * **Staging:** 2 replicas
  * **Production:** 3+ replicas across multiple availability zones

  **Scaling Considerations:**

  * Each replica needs full resource allocation (6 CPU / 12Gi by default)
  * Database connections scale with replicas
  * Session management requires sticky sessions or external session store
</ParamField>

<ParamField path="web.service.type" type="string" default="">
  Kubernetes service type for web application.

  **Auto-Detection:** When empty:

  * `"ClusterIP"` if ingress is enabled
  * `"LoadBalancer"` if ingress is disabled

  **Valid Values:**

  * `"ClusterIP"` - Internal cluster access only
  * `"LoadBalancer"` - Expose via cloud load balancer
  * `"NodePort"` - Expose on node ports

  **Production Recommendation:** Use `"ClusterIP"` with ingress for production deployments.
</ParamField>

### `web.tls.*`

Application-level TLS configuration.

<ParamField path="web.tls.autoGenerate" type="boolean" default="false">
  Automatically generate self-signed TLS certificate.

  **When Enabled:**

  * Certificate generated during Helm deployment
  * Persisted across upgrades using `lookup` function
  * Includes all hostnames from `hosts` array

  **Use Cases:**

  * Development environments
  * Testing HTTPS functionality
  * Environments without proper certificate management

  **Production Recommendation:** Use ingress TLS with proper certificates instead.
</ParamField>

<ParamField path="web.tls.duration" type="integer" default="365">
  Certificate validity period in days (for auto-generated certificates).
</ParamField>

<ParamField path="web.tls.hosts" type="array" default="[&#x22;localhost&#x22;, &#x22;127.0.0.1&#x22;]">
  Additional hostnames to include in auto-generated certificate.

  **Example:**

  ```yaml theme={null}
  web:
    tls:
      autoGenerate: true
      hosts:
        - localhost
        - crewai.local
        - 10.0.0.100
  ```
</ParamField>

### `web.resources.*`

Resource limits and requests for web application container.

<ParamField path="web.resources.limits.cpu" type="string" default="6">
  CPU limit for web pod.
</ParamField>

<ParamField path="web.resources.limits.memory" type="string" default="12Gi">
  Memory limit for web pod.
</ParamField>

<ParamField path="web.resources.requests.cpu" type="string" default="500m">
  Guaranteed CPU allocation for web pod.
</ParamField>

<ParamField path="web.resources.requests.memory" type="string" default="6Gi">
  Guaranteed memory allocation for web pod.
</ParamField>

<ParamField path="web.terminationGracePeriodSeconds" type="integer" default="30">
  Seconds to allow for graceful pod shutdown.

  **Purpose:** Allows in-flight requests to complete before pod termination.

  **Production Recommendation:** Set to 60-120 seconds for production to handle long-running requests.
</ParamField>

<ParamField path="web.nodeSelector" type="object" default="{}">
  Node selector for web pod placement.

  **Example:**

  ```yaml theme={null}
  web:
    nodeSelector:
      node-role.kubernetes.io/frontend: "true"
      topology.kubernetes.io/zone: us-west-2a
  ```

  **Use Cases:**

  * Ensure web pods run on nodes with specific capabilities
  * Separate web workload from database or worker workload
  * Control pod placement across availability zones
</ParamField>

### `web.readinessProbe.*`

Readiness probe configuration for web pods.

<ParamField path="web.readinessProbe.initialDelaySeconds" type="integer" default="10">
  Seconds to wait before first readiness check.

  **Tuning:** Increase if application takes longer to start.
</ParamField>

<ParamField path="web.readinessProbe.periodSeconds" type="integer" default="10">
  Seconds between readiness checks.
</ParamField>

<ParamField path="web.readinessProbe.timeoutSeconds" type="integer" default="5">
  Readiness probe timeout.
</ParamField>

<ParamField path="web.readinessProbe.successThreshold" type="integer" default="1">
  Consecutive successes required.
</ParamField>

<ParamField path="web.readinessProbe.failureThreshold" type="integer" default="3">
  Consecutive failures before pod marked not ready.

  **Purpose:** Removes pod from service load balancing during failures, preventing request failures.
</ParamField>

### `web.ingress.*`

Ingress configuration for external web access.

<ParamField path="web.ingress.enabled" type="boolean" default="false">
  Enable ingress for web application.

  **Production Recommendation:** Enable for production deployments.
</ParamField>

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

  **Common Values:**

  * `"nginx"` - NGINX Ingress Controller
  * `"alb"` - AWS Application Load Balancer Controller
  * `"traefik"` - Traefik Ingress
  * `"istio"` - Istio Virtual Service (see `virtualService.*`)
</ParamField>

<ParamField path="web.ingress.host" type="string" default="">
  Hostname for ingress routing.

  **Example:** `"crewai.company.com"`

  **Required:** Must be set when ingress is enabled.
</ParamField>

<ParamField path="web.ingress.path" type="string" default="/">
  URL path for ingress routing.

  **Use Cases:**

  * Root path: `"/"` (most common)
  * Subpath deployment: `"/crewai"`
</ParamField>

<ParamField path="web.ingress.pathType" type="string" default="Prefix">
  Path matching type.

  **Valid Values:**

  * `"Prefix"` - Match path prefix
  * `"Exact"` - Exact path match
  * `"ImplementationSpecific"` - Controller-specific
</ParamField>

<ParamField path="web.ingress.annotations" type="object" default="{}">
  Custom annotations for the Ingress resource.

  **Purpose:** Add ingress controller-specific annotations not covered by the built-in configuration options.

  **Example:**

  ```yaml theme={null}
  web:
    ingress:
      annotations:
        cert-manager.io/cluster-issuer: "letsencrypt-prod"
        nginx.ingress.kubernetes.io/rate-limit: "100"
        external-dns.alpha.kubernetes.io/hostname: "crewai.example.com"
  ```

  **Note:** These annotations are applied in addition to the controller-specific annotations (ALB, NGINX) that are automatically generated based on other configuration values like `web.ingress.alb.*` and `web.ingress.nginx.*`.
</ParamField>

### `web.ingress.alb.*`

AWS Application Load Balancer specific configuration.

<ParamField path="web.ingress.alb.scheme" type="string" default="internet-facing">
  ALB scheme.

  **Valid Values:**

  * `"internet-facing"` - Public internet access
  * `"internal"` - VPC-internal only
</ParamField>

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

  **Valid Values:**

  * `"ip"` - Direct pod IP routing (recommended for EKS)
  * `"instance"` - NodePort routing
</ParamField>

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

  **Example:** `"arn:aws:acm:us-west-2:123456789012:certificate/abc-def-ghi"`

  **Required:** For HTTPS access via ALB.
</ParamField>

<ParamField path="web.ingress.alb.sslPolicy" type="string" default="ELBSecurityPolicy-TLS-1-2-2017-01">
  ALB SSL/TLS policy.

  **Common Policies:**

  * `"ELBSecurityPolicy-TLS-1-2-2017-01"` - TLS 1.2+ (recommended)
  * `"ELBSecurityPolicy-TLS-1-2-Ext-2018-06"` - Extended TLS 1.2+
  * `"ELBSecurityPolicy-FS-1-2-Res-2020-10"` - Forward secrecy enforced
</ParamField>

### `web.ingress.nginx.*`

NGINX Ingress Controller specific configuration.

<ParamField path="web.ingress.nginx.sslRedirect" type="boolean" default="false">
  Automatically redirect HTTP to HTTPS.

  **Production Recommendation:** Enable when TLS is configured.
</ParamField>

<ParamField path="web.ingress.nginx.proxyBodySize" type="string" default="50m">
  Maximum allowed size for client request body.

  **Use Cases:**

  * File uploads
  * Large API payloads

  **Syntax:** `"<number>m"` for megabytes, `"<number>g"` for gigabytes, `"0"` for unlimited.
</ParamField>

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

  **Purpose:** Allow browser-based applications from different origins to access the API.
</ParamField>

<ParamField path="web.ingress.nginx.corsAllowMethods" type="string" default="GET, PUT, POST, DELETE, PATCH, OPTIONS">
  Allowed HTTP methods for CORS.
</ParamField>

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

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

  **Production Recommendation:** Specify exact origins instead of `"*"`:

  ```yaml theme={null}
  web:
    ingress:
      nginx:
        corsAllowOrigin: "https://app.company.com,https://admin.company.com"
  ```
</ParamField>

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

<ParamField path="web.ingress.nginx.sessionAffinity" type="boolean" default="true">
  Enable sticky sessions (session affinity).

  **Purpose:** Routes requests from the same client to the same backend pod.

  **When Needed:**

  * In-memory session storage
  * WebSocket connections
  * Application-specific caching
</ParamField>

<ParamField path="web.ingress.nginx.sessionCookieName" type="string" default="_session_id">
  Cookie name for session affinity.
</ParamField>

<ParamField path="web.ingress.nginx.sessionCookiePath" type="string" default="/">
  Cookie path for session affinity.
</ParamField>

<ParamField path="web.ingress.nginx.whitelistSourceRange" type="string" default="">
  IP CIDR ranges allowed to access ingress.

  **Default Behavior:** When empty (default), no IP restrictions are applied.

  **Example - Multiple Ranges:**

  ```yaml theme={null}
  web:
    ingress:
      nginx:
        whitelistSourceRange: "10.0.0.0/8,172.16.0.0/12,203.0.113.0/24"
  ```

  **Production Recommendation:** Restrict to known corporate IP ranges or VPN endpoints for enhanced security.
</ParamField>

<ParamField path="web.ingress.nginx.backendProtocol" type="string" default="">
  Backend protocol for NGINX to use when communicating with the web pods.

  **Auto-Detection:** When empty (default), automatically sets based on `web.enableSslFromPuma`:

  * `"HTTPS"` if `web.enableSslFromPuma` is `true`
  * `"HTTP"` if `web.enableSslFromPuma` is `false`

  **Valid Values:**

  * `""` - Auto-detect (recommended)
  * `"HTTP"` - Force HTTP backend communication
  * `"HTTPS"` - Force HTTPS backend communication

  **Use Cases:**

  * Most deployments should use auto-detection (leave empty)
  * Override only when custom TLS termination or protocol handling is needed

  **Note:** Corresponds to the `nginx.ingress.kubernetes.io/backend-protocol` annotation.
</ParamField>

<ParamField path="web.ingress.nginx.tls.enabled" type="boolean" default="true">
  Enable TLS for NGINX ingress.
</ParamField>

<ParamField path="web.ingress.nginx.tls.secretName" type="string" default="">
  Name of Kubernetes TLS secret.

  **Create Secret:**

  ```bash theme={null}
  kubectl create secret tls crewai-tls \
    --cert=tls.crt \
    --key=tls.key
  ```
</ParamField>

### `web.virtualService.*`

Istio Virtual Service configuration (alternative to standard ingress).

<ParamField path="web.virtualService.enabled" type="boolean" default="false">
  Enable Istio Virtual Service instead of standard ingress.
</ParamField>

<ParamField path="web.virtualService.host" type="string" default="">
  Hostname for virtual service routing.
</ParamField>

<ParamField path="web.virtualService.gateway" type="string" default="">
  Istio Gateway resource name.

  **Example:**

  ```yaml theme={null}
  web:
    virtualService:
      enabled: true
      host: "crewai.company.com"
      gateway: "istio-system/public-gateway"
  ```
</ParamField>

### `web.gateway.*`

Gateway API HTTPRoute configuration (alternative to Ingress).

<Note>
  **Gateway API vs Ingress:** Gateway API is the modern successor to Ingress, offering better multi-tenancy, advanced routing, and standardization. It's natively supported on GKE and recommended for new deployments.
</Note>

<ParamField path="web.gateway.enabled" type="boolean" default="false">
  Enable Gateway API HTTPRoute for web application.

  **When Enabled:**

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

  **When Disabled:**

  * No HTTPRoute created for web service
  * Use `web.ingress.*` or `web.virtualService.*` instead

  **Example:**

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

  web:
    gateway:
      enabled: true
      hostnames:
        - crewai.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 `unconditional drop overload` errors caused by Rails' HostAuthorization middleware blocking GKE's default health check behavior.
  </Note>
</ParamField>

<ParamField path="web.gateway.hostnames" type="array" default="[]">
  Hostnames for web service routing via Gateway API.

  **Default Behavior:** When empty, defaults to `[envVars.APPLICATION_HOST]`.

  **Purpose:** Specifies which hostnames this HTTPRoute should match. Traffic to these hostnames will be routed to the web service.

  **Example - Single Hostname:**

  ```yaml theme={null}
  web:
    gateway:
      enabled: true
      hostnames:
        - crewai.company.com
  ```

  **Example - Multiple Hostnames:**

  ```yaml theme={null}
  web:
    gateway:
      enabled: true
      hostnames:
        - crewai.company.com
        - app.company.com
        - www.crewai.company.com
  ```

  **Example - Use APPLICATION\_HOST (Default):**

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

  web:
    gateway:
      enabled: true
      hostnames: []  # Defaults to [crewai.company.com]
  ```

  <Warning>
    All hostnames must be covered by the Gateway's TLS certificate (if using HTTPS). For GCP-managed certificates, add all hostnames to the certificate map.
  </Warning>
</ParamField>

**Complete Example:**

```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
    - name: http
      protocol: HTTP
      port: 80

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

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

***
