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

# Webhook Gateway setup

> Set up the Webhook Gateway microservice — the public endpoint that receives incoming webhook calls from external systems and routes them to FlowX processes via Kafka.

## Dependencies

Before setting up the Webhook Gateway, ensure you have the following dependencies in place:

* **PostgreSQL** database for storing webhook registration data
* **Kafka** for publishing process start events
* **Keycloak** (or compatible OAuth2 provider) for authentication and authorization
* **SpiceDB** for fine-grained authorization

## Infrastructure prerequisites

| Component | Description |
| - | - |
| PostgreSQL | Dedicated database named `webhook_gateway` |
| Kafka | Message broker for triggering process starts |
| Keycloak | Identity provider for service authentication |
| SpiceDB | Authorization service for workspace validation |

***

## Configuration

### Authorization configuration

The Webhook Gateway validates incoming tokens with the JWT public key mechanism and authenticates to other FlowX services with a dedicated service account (the `mainIdentity` client registration) in the service-accounts realm:

| Environment Variable | Description | Default Value |
| - | - | - |
| `SECURITY_TYPE` | Token validation mechanism (JWT public key validation) | `jwt-public-key` |
| `SECURITY_OAUTH2_BASESERVERURL` | Base URL of the Keycloak server | |
| `SECURITY_OAUTH2_SAREALM` | Service-accounts realm ID | `00000002-0002-4002-8002-000000000002` |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_MAINIDENTITY_CLIENTID` | Service account client ID | `flowx-webhook-gateway-sa` |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_MAINIDENTITY_CLIENTSECRET` | Service account client secret (Keycloak-issued) | |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_ANONYMOUSIDENTITY_CLIENTID` | Anonymous service account client ID, used for [anonymous runtime access](https://docs.flowx.ai/6.x/docs/platform-deep-dive/user-roles-management/anonymous-runtime-access.md) | `flowx-anonymous-sa` |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_ANONYMOUSIDENTITY_CLIENTSECRET` | Anonymous service account client secret | |
| `SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_MAINAUTHPROVIDER_TOKENURI` | Provider token URI, resolved against the service-accounts realm | `${SECURITY_OAUTH2_BASESERVERURL}/realms/${SECURITY_OAUTH2_SAREALM}/protocol/openid-connect/token` |

> [!WARNING]
>
> **Upgrading from 5.1.x?** Remove the legacy opaque-token env vars: `SECURITY_OAUTH2_REALM`, `SECURITY_OAUTH2_CLIENT_CLIENTID`, `SECURITY_OAUTH2_CLIENT_CLIENTSECRET`, and `SECURITY_OAUTH2_SERVICEACCOUNT_ADMIN_*`. These belong to the removed introspection model and prevent the service from starting on 5.9.x. See the [authentication and IAM migration guide](https://docs.flowx.ai/5.9/migrating-from-5.1-lts/authentication-iam.md) for the full list.

> [!NOTE]
>
> The Webhook Gateway exposes `/webhooks/**` as public (unauthenticated) paths for receiving incoming webhooks. The `/api/**` paths require a valid JWT token.

***

### PostgreSQL configuration

The Webhook Gateway uses its own dedicated PostgreSQL database for storing webhook registration data.

| Environment Variable | Description | Default Value |
| - | - | - |
| `SPRING_DATASOURCE_URL` | JDBC connection URL for PostgreSQL | `jdbc:postgresql://postgresql:5432/webhook_gateway` |
| `SPRING_DATASOURCE_USERNAME` | Database username | `flowx` |
| `SPRING_DATASOURCE_PASSWORD` | Database password | - |

> [!WARNING]
>
> Ensure the `webhook_gateway` database is created before deploying the service. The Webhook Gateway will manage its own schema migrations via Liquibase.

***

### Kafka configuration

The Webhook Gateway is a **producer-only** service — it publishes messages to Kafka but does not consume from any topics. It publishes to two topics: one for starting new processes and one for resuming waiting process instances.

#### Core Kafka settings

| Environment Variable | Description | Default Value |
| - | - | - |
| `SPRING_KAFKA_BOOTSTRAP_SERVERS` | Address of the Kafka server(s) | `localhost:9092` |
| `SPRING_KAFKA_SECURITY_PROTOCOL` | Security protocol for Kafka connections | `PLAINTEXT` |
| `KAFKA_AUTHEXCEPTIONRETRYINTERVAL` | Retry interval after authorization exceptions (seconds) | `10` |

#### OAuth authentication (when using SASL\_PLAINTEXT)

| Environment Variable | Description | Default Value |
| - | - | - |
| `KAFKA_OAUTH_CLIENT_ID` | OAuth client ID | `kafka` |
| `KAFKA_OAUTH_CLIENT_SECRET` | OAuth client secret | `kafka-secret` |
| `KAFKA_OAUTH_TOKEN_ENDPOINT_URI` | OAuth token endpoint | `kafka.auth.localhost` |

> [!NOTE]
>
> When using the `kafka-auth` profile, the security protocol will automatically be set to `SASL_PLAINTEXT` and the SASL mechanism will be set to `OAUTHBEARER`.

#### Topic naming configuration

| Environment Variable | Description | Default Value |
| - | - | - |
| `KAFKA_TOPIC_NAMING_PACKAGE` | Package prefix for topic names | `ai.flowx.` |
| `KAFKA_TOPIC_NAMING_ENVIRONMENT` | Environment segment for topic names | ` ` |
| `KAFKA_TOPIC_NAMING_VERSION` | Version suffix for topic names | `.v1` |
| `KAFKA_TOPIC_NAMING_SEPARATOR` | Primary separator for topic names | `.` |
| `KAFKA_TOPIC_NAMING_SEPARATOR2` | Secondary separator for topic names | `-` |

#### Kafka topics

The Webhook Gateway publishes to the following Kafka topics:

| Environment Variable | Description | Default Value |
| - | - | - |
| `KAFKA_TOPIC_PROCESS_START_OUT` | Topic for triggering process starts from webhook events (Message Start Event) | `ai.flowx.core.trigger.start-for-event.process.v1` |
| `KAFKA_TOPIC_PROCESS_EVENT_MESSAGE` | Topic for resuming running process instances from webhook events (Message Catch Intermediate Event) | `ai.flowx.core.message.event.process.v1` |

***

### CAS lib configuration (SpiceDB)

| Environment Variable | Description | Default Value |
| - | - | - |
| `FLOWX_SPICEDB_HOST` | SpiceDB hostname | `spicedb` |
| `FLOWX_SPICEDB_PORT` | SpiceDB gRPC port | `50051` |
| `FLOWX_SPICEDB_TOKEN` | SpiceDB authentication token | - |
| `FLOWX_LIB_CASCLIENT_RUNTIME_IMPLEMENTATION` | Runtime authorization backend used by the CAS client. `CUSTOM` routes checks through authorization-system; `SPICEDB` delegates to SpiceDB. Keep the default unless instructed by FlowX. | `CUSTOM` |

***

### Service communication

The Webhook Gateway communicates with the following FlowX services:

| Environment Variable | Description | Default Value |
| - | - | - |
| `FLOWX_LIB_SECURITY_SERVICES_ORGANIZATIONMANAGER_BASEURL` | Organization Manager base URL | `http://organization-manager:80` |
| `FLOWX_LIB_CASCLIENT_SERVICES_AUTHORIZATIONSYSTEM_BASEURL` | Authorization System base URL | `http://authorization-system:80` |

***

### Logging configuration

| Environment Variable | Description | Default Value |
| - | - | - |
| `LOGGING_LEVEL_ROOT` | Root logging level | `INFO` |
| `LOGGING_LEVEL_APP` | Application-specific log level | `INFO` |

***

## Secrets management

The Webhook Gateway requires several secrets to be configured. These should be stored securely and referenced via Kubernetes secrets or a secrets management solution.

| Secret Name | Description |
| - | - |
| `SPRING_DATASOURCE_PASSWORD` | PostgreSQL database password |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_MAINIDENTITY_CLIENTSECRET` | Keycloak service account secret |
| `FLOWX_SPICEDB_TOKEN` | SpiceDB authentication token |
| `KAFKA_OAUTH_CLIENT_SECRET` | Kafka OAuth client secret (if using OAuth) |

***

## Deployment

### Helm values example

Below is an example Helm values configuration for deploying the Webhook Gateway:

```yaml theme={"dark"}
fullnameOverride: webhook-gateway

image:
  registry: <your-registry>
  repository: webhook-gateway

replicaCount: 1

env:
  SPRING_PROFILES_ACTIVE: production

  # PostgreSQL
  SPRING_DATASOURCE_URL: jdbc:postgresql://postgresql:5432/webhook_gateway
  SPRING_DATASOURCE_USERNAME: flowx

  # Kafka
  SPRING_KAFKA_BOOTSTRAP_SERVERS: kafka:9092

  # OAuth2
  SECURITY_TYPE: jwt-public-key
  SECURITY_OAUTH2_BASESERVERURL: https://keycloak.example.com/auth

  # SpiceDB
  FLOWX_SPICEDB_HOST: spicedb
  FLOWX_SPICEDB_PORT: 50051

# Secrets configuration
extraEnvVarsMultipleSecretsCustomKeys:
  - name: postgresql-generic
    secrets:
      SPRING_DATASOURCE_PASSWORD: postgresql-password-key
  - name: flowx-auth
    secrets:
      SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_MAINIDENTITY_CLIENTSECRET: keycloakWebhookGatewayClientSecret
  - name: spicedb-generic
    secrets:
      FLOWX_SPICEDB_TOKEN: spicedb-token

rbac:
  create: true

ingress:
  enabled: true
  admin:
    enabled: true
    path: /webhooks

podLabels:
  flowx.ai/network-log: "true"
  flowx.ai/egress-s-kafka: "true"
  flowx.ai/egress-s-postgresql: "true"
  flowx.ai/routing-name: "webhook-gateway"
  flowx.ai/prometheus-scrape: "webhook-gateway"
```

> [!NOTE]
>
> The `image.registry` and `image.repository` split applies to **5.9.4 and later**. To redirect every chart at once, use `global.imageRegistry`. See [Container images and registry](https://docs.flowx.ai/6.x/setup-guides/setup-guides-overview.md#container-images-and-registry).

> [!NOTE]
>
> Unlike most FlowX services, the Webhook Gateway requires ingress to be enabled because it receives incoming HTTP requests from external systems on the `/webhooks` path.

### Network policies

The Webhook Gateway requires network access to the following services:

| Service | Purpose | Pod Label |
| - | - | - |
| Kafka | Message broker communication | `flowx.ai/egress-s-kafka` |
| PostgreSQL | Webhook registration storage | `flowx.ai/egress-s-postgresql` |
| Keycloak | Authentication | `flowx.ai/egress-s-keycloak` |
| SpiceDB | Authorization | `flowx.ai/egress-s-spicedb` |
| Organization Manager | Organization context resolution | `flowx.ai/egress-s-organization-manager` |
| Authorization System | Access control | `flowx.ai/egress-s-authorization-system` |

***

## Monitoring

The Webhook Gateway exposes Prometheus metrics for monitoring. Turn on scraping by setting the pod label:

```yaml theme={"dark"}
podLabels:
  flowx.ai/prometheus-scrape: "webhook-gateway"
```

### Health endpoints

| Endpoint | Description |
| - | - |
| `/actuator/health` | Health check endpoint |
| `/actuator/metrics` | Prometheus metrics endpoint |
| `/actuator/info` | App info endpoint |

***

## Verify your setup

> [!TIP]
>
> The Webhook Gateway pod is running and healthy: `kubectl get pods -l app=webhook-gateway`

> [!TIP]
>
> The health endpoint returns HTTP 200: `curl http://webhook-gateway:8080/actuator/health`

> [!TIP]
>
> Database migrations completed successfully — check pod logs for `Liquibase: Update has been successful`

> [!TIP]
>
> SpiceDB connection is established — check pod logs for successful CAS client initialization

> [!TIP]
>
> The `/webhooks` ingress path is accessible from external systems

***

## Ingress and CORS

The Webhook Gateway is exposed externally on the admin host. Routing is configured through the FlowX Helm chart, which renders either a Kubernetes Ingress (default) or a Gateway API HTTPRoute per service. The path is preserved end-to-end (no rewrite), because the webhook endpoint URL is the same on the backend as on the client.

### Service route

| Host group | External path | Backend receives | Notes |
| - | - | - | - |
| admin | `/webhooks` | `/webhooks/...` | Path preserved |

The path is set through `services.webhook-gateway.ingress.admin.path` (or `services.webhook-gateway.gateway.admin.paths`) in the chart values. No rewrite is applied — webhook URLs your upstream systems POST to must match the path exactly.

### CORS configuration

| Environment Variable | Description | Default Value |
| - | - | - |
| `APPLICATION_CORS_ALLOWORIGIN` | Comma-separated list of origins allowed to call this service from the browser. Most webhook traffic is server-to-server and unaffected; set this only if a Designer or integration UI calls the Webhook Gateway from the browser. | `-` |

Allowed methods, allowed headers, and credential handling are baked into the service's `application.yaml` with safe defaults. Override these only if you have a non-standard requirement.

For the complete route reference, Gateway API HTTPRoute configuration, and route customization, see the [ingress configuration guide](https://docs.flowx.ai/6.x/setup-guides/ingress-configuration.md).

***

## Troubleshooting

> [accordion] Database connection failures
>
> **Symptoms:** Service fails to start with database connection errors.
>
> **Solutions:**
>
> 1. Verify the `webhook_gateway` database exists in PostgreSQL
> 2. Check that the database user has appropriate permissions
> 3. Ensure network connectivity between the pod and PostgreSQL service
> 4. Verify the JDBC URL format is correct

> [accordion] SpiceDB connection failures
>
> **Symptoms:** Authorization errors or service fails to initialize CAS client.
>
> **Solutions:**
>
> 1. Verify SpiceDB is running and reachable at the configured host and port
> 2. Check that the SpiceDB token is correct
> 3. Ensure network policies allow gRPC traffic to SpiceDB on port `50051`
> 4. Review pod logs for specific CAS client error messages

> [accordion] Kafka publishing failures
>
> **Symptoms:** Webhook events not triggering process starts.
>
> **Solutions:**
>
> 1. Verify Kafka bootstrap servers are reachable
> 2. Check that the `ai.flowx.core.trigger.start-for-event.process.v1` topic exists
> 3. Ensure the service has producer permissions on the topic
> 4. Review pod logs for Kafka producer errors

> [accordion] Webhook endpoint not reachable
>
> **Symptoms:** External systems cannot reach the webhook URL.
>
> **Solutions:**
>
> 1. Verify ingress is enabled and the `/webhooks` path is configured
> 2. Check that network policies allow inbound traffic to the Webhook Gateway
> 3. Ensure DNS resolves correctly for the webhook URL
> 4. Verify the service is listening on port `8080`

> [accordion] Service account authentication errors
>
> **Symptoms:** 401/403 errors when communicating with other FlowX services.
>
> **Solutions:**
>
> 1. Verify the Keycloak service account is properly configured
> 2. Check that client secrets match between configuration and Keycloak
> 3. Ensure the service account has required roles assigned
> 4. Verify `SECURITY_TYPE` is set to `jwt-public-key`

***

## Related resources

> [card] [SpiceDB Configuration](https://docs.flowx.ai/6.x/setup-guides/spicedb.md)
>
> Fine-grained authorization setup

> [card] [Kafka Authentication](https://docs.flowx.ai/6.x/setup-guides/kafka-authentication-config.md)
>
> Configure Kafka security and authentication

> [card] [IAM Configuration](https://docs.flowx.ai/6.x/setup-guides/access-management/configuring-an-iam-solution.md)
>
> Identity and access management setup


## Related topics

- [Incoming Webhooks](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/incoming-webhooks.md)
- [Deployment guidelines v5.6.0](https://docs.flowx.ai/release-notes/v5.x/v5.6.0-march-2026/deployment-guidelines-v5.6.md)
- [FlowX.AI architecture: services, layers, and data flow](https://docs.flowx.ai/6.x/docs/platform-overview/flowx-architecture.md)
- [Deployment guidelines v5.12](https://docs.flowx.ai/release-notes/v5.x/v5.12.0-september-2026/deployment-guidelines-v5.12.md)
- [File Gateway setup](https://docs.flowx.ai/6.x/setup-guides/file-gateway-setup.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.