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

# Ingress configuration guide

> Centralized guide for configuring Kubernetes ingress for FlowX.AI services

This guide provides the standard ingress configuration pattern for all FlowX.AI services that expose REST APIs or event streams to external clients.

## Overview

FlowX.AI services use Kubernetes ingress with NGINX to expose APIs to the FlowX Designer and other external consumers. All services follow a consistent pattern with specific CORS headers required for multi-tenant workspace identification.

## Standard ingress pattern

### Common template

Most FlowX.AI services use this standard ingress configuration:

```yaml theme={"system"}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: <service-name>-admin
  annotations:
    nginx.ingress.kubernetes.io/client-body-buffer-size: "25M"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,flowx-platform,Fx-Workspace-Id"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://your-designer-domain.com,http://localhost:4200"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "25m"
    nginx.ingress.kubernetes.io/rewrite-target: "<rewrite-pattern>"
spec:
  ingressClassName: nginx
  rules:
  - host: admin.your-domain.com
    http:
      paths:
      - path: <service-path>
        pathType: ImplementationSpecific
        backend:
          service:
            name: <service-name>
            port:
              name: http
```

### Service-specific values

Replace the placeholders with service-specific values from this table:

| Service              | Ingress Name                      | Service Path                                | Rewrite Target |                   |                     |
| -------------------- | --------------------------------- | ------------------------------------------- | -------------- | ----------------- | ------------------- |
| Admin                | `admin-admin`                     | `/((.*))` or \`/admin(/                     | \$)(.\*)\`     | `/$2`             |                     |
| Application Manager  | `application-manager-admin`       | \`/appmanager(/                             | \$)(.\*)\`     | `/$2`             |                     |
| Audit Core           | `audit-core-admin`                | \`/audit(/                                  | \$)(.\*)(/     | \$)(.\*)\`        | `/$2`               |
| Authorization System | `authorization-system-admin`      | \`/auth/api(/                               | \$)(.\*)(/     | \$)(.\*)\`        | `/api/$2`           |
| Integration Designer | `integration-designer-admin`      | \`/integration(/                            | \$)(.\*)\`     | `/$2`             |                     |
| Process Engine       | `process-engine-admin`            | \`/onboarding/api(/                         | \$)(.\*)(/     | \$)(.\*)\`        | `/api/$2`           |
| Process Engine       | `process-engine-admin-instances`  | \`/api/instances(/                          | \$)(.\*)(/     | \$)(.\*)\`        | `/api/instances/$2` |
| Runtime Manager      | `runtime-manager-admin`           | \`/rtm/api/runtime(/                        | \$)(.\*)\`     | `/api/runtime/$2` |                     |
| Runtime Manager      | `runtime-manager-admin-instances` | `/rtm/api/(runtime\|runtime-internal)/(.*)` | `/api/$1/$2`   |                   |                     |
| Task Management      | `task-management-plugin-admin`    | \`/task(/                                   | \$)(.\*)(/     | \$)(.\*)\`        | `/$2`               |

## Standard annotations explained

### Required annotations

| Annotation                                            | Value                      | Purpose                                               |
| ----------------------------------------------------- | -------------------------- | ----------------------------------------------------- |
| `nginx.ingress.kubernetes.io/client-body-buffer-size` | `25M`                      | Buffer size for client request body                   |
| `nginx.ingress.kubernetes.io/proxy-body-size`         | `25m`                      | Maximum size of client request body                   |
| `nginx.ingress.kubernetes.io/cors-allow-credentials`  | `true`                     | Allow credentials in CORS requests                    |
| `nginx.ingress.kubernetes.io/enable-cors`             | `true`                     | Enable CORS support                                   |
| `nginx.ingress.kubernetes.io/cors-allow-headers`      | Includes `Fx-Workspace-Id` | Headers allowed in CORS requests (workspace required) |
| `nginx.ingress.kubernetes.io/cors-allow-origin`       | Designer domain(s)         | Origins allowed for CORS requests                     |
| `nginx.ingress.kubernetes.io/rewrite-target`          | Service-specific           | URL rewrite pattern                                   |

### Workspace identification header

<Warning>
  The `Fx-Workspace-Id` header is **required** in the `cors-allow-headers` annotation for all services except Events Gateway.
</Warning>

The `Fx-Workspace-Id` header enables multi-tenant workspace identification. Include it in the CORS allowed headers:

```yaml theme={"system"}
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,flowx-platform,Fx-Workspace-Id"
```

## Events Gateway exception

The Events Gateway service handles Server-Sent Events (SSE) and uses a simplified ingress configuration without the `cors-allow-headers` annotation:

```yaml theme={"system"}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: events-gateway-admin
  annotations:
    nginx.ingress.kubernetes.io/client-body-buffer-size: "25M"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://your-designer-domain.com,http://localhost:4200"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "25m"
    nginx.ingress.kubernetes.io/rewrite-target: "/api/events/$2"
spec:
  ingressClassName: nginx
  rules:
  - host: admin.your-domain.com
    http:
      paths:
      - path: /api/events(/|$)(.*)(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: events-gateway
            port:
              name: http
```

<Info>
  Events Gateway does not require the `Fx-Workspace-Id` header in its ingress configuration because it handles real-time SSE connections with different security requirements.
</Info>

## Environment-specific customization

### Required changes per environment

Update these values for your specific environment:

1. **CORS Origins** - Replace with your actual domains:
   ```yaml theme={"system"}
   nginx.ingress.kubernetes.io/cors-allow-origin: "https://designer.yourcompany.com,https://admin.yourcompany.com"
   ```

2. **Host** - Set to your ingress hostname:
   ```yaml theme={"system"}
   rules:
   - host: admin.yourcompany.com
   ```

3. **TLS Configuration** - Add TLS section if using HTTPS:
   ```yaml theme={"system"}
   tls:
   - hosts:
     - admin.yourcompany.com
     secretName: admin-tls-secret
   ```

### Development vs Production

**Development:**

```yaml theme={"system"}
nginx.ingress.kubernetes.io/cors-allow-origin: "http://localhost:4200,http://localhost:4300"
```

**Production:**

```yaml theme={"system"}
nginx.ingress.kubernetes.io/cors-allow-origin: "https://designer.yourcompany.com"
```

## Complete example

Here's a complete, production-ready ingress configuration for the Admin service:

```yaml theme={"system"}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: admin-admin
  namespace: flowx-production
  annotations:
    nginx.ingress.kubernetes.io/client-body-buffer-size: "25M"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,flowx-platform,Fx-Workspace-Id"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://designer.yourcompany.com"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "16m"
    nginx.ingress.kubernetes.io/rewrite-target: "/$2"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  rules:
  - host: admin.yourcompany.com
    http:
      paths:
      - path: /((.*))
        pathType: ImplementationSpecific
        backend:
          service:
            name: admin
            port:
              name: http
  tls:
  - hosts:
    - admin.yourcompany.com
    secretName: admin-tls-secret
```

## Troubleshooting

### CORS errors

**Problem:** Browser shows CORS policy errors

**Solution:** Verify that:

1. `Fx-Workspace-Id` is included in `cors-allow-headers`
2. Your origin is listed in `cors-allow-origin`
3. `enable-cors` is set to `true`

### 413 Request Entity Too Large

**Problem:** Large file uploads fail

**Solution:** Increase buffer sizes:

```yaml theme={"system"}
nginx.ingress.kubernetes.io/client-body-buffer-size: "50M"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
```

### 502 Bad Gateway

**Problem:** Service unreachable through ingress

**Solution:** Verify:

1. Service name matches the backend service
2. Port name is correct (typically `http`)
3. Service is running and healthy

### Path routing issues

**Problem:** Requests return 404

**Solution:** Check:

1. Path pattern matches your URL structure
2. Rewrite target correctly transforms the path
3. Service expects the rewritten path format

## Best practices

<CardGroup cols={2}>
  <Card title="Security" icon="shield">
    * Use HTTPS in production
    * Restrict CORS origins to known domains
    * Never use wildcards in production CORS origins
    * Keep buffer sizes reasonable (25M is sufficient for most use cases)
  </Card>

  <Card title="Performance" icon="gauge-high">
    * Use appropriate buffer sizes for your workload
    * Monitor ingress metrics
    * Configure timeouts for long-running requests
    * Consider connection limits for SSE endpoints
  </Card>

  <Card title="Maintainability" icon="wrench">
    * Use consistent naming conventions
    * Document any deviations from standard pattern
    * Keep annotations organized alphabetically
    * Use ConfigMaps for shared values
  </Card>

  <Card title="Reliability" icon="shield-check">
    * Always include health check paths
    * Configure proper timeouts
    * Use multiple replicas for high availability
    * Monitor ingress logs for errors
  </Card>
</CardGroup>

## Additional resources

<Card title="NGINX Ingress Controller Documentation" href="https://kubernetes.github.io/ingress-nginx/" icon="book" />

<Card title="Kubernetes Ingress Documentation" href="https://kubernetes.io/docs/concepts/services-networking/ingress/" icon="book" />
