> ## 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
* **Redis** for caching
* **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   |
| Redis      | Caching layer for improved performance         |
| 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](/5.9/docs/platform-deep-dive/user-roles-management/anonymous-runtime-access) | `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](/5.9/migrating-from-5.1-lts/authentication-iam) for the full list.
</Warning>

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

***

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

***

### Redis configuration

Webhook Gateway uses Redis for caching. Configure Redis connection using the standard Redis environment variables.

**Quick reference:**

| Environment Variable         | Description                   | Example Value | Status          |
| ---------------------------- | ----------------------------- | ------------- | --------------- |
| `SPRING_DATA_REDIS_HOST`     | Redis server hostname         | `localhost`   | **Recommended** |
| `SPRING_DATA_REDIS_PORT`     | Redis server port             | `6379`        | **Recommended** |
| `SPRING_DATA_REDIS_PASSWORD` | Redis authentication password | -             | **Recommended** |
| `REDIS_TTL`                  | Cache TTL in milliseconds     | `5000000`     | Optional        |

<Info>
  Both `SPRING_DATA_REDIS_*` and `SPRING_REDIS_*` variable prefixes are supported. The `SPRING_DATA_REDIS_*` prefix is the modern Spring Boot standard and is recommended for new deployments.
</Info>

<Info>
  For advanced Redis deployment modes (Sentinel, Cluster) and SSL/TLS setup, see the [Redis Configuration](/5.1/setup-guides/redis-configuration) guide. Note that Sentinel and Cluster modes are only supported by the Events Gateway service.
</Info>

***

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

<Info>
  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`.
</Info>

#### 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_REDIS_PASSWORD`                                                | Redis authentication 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={"system"}
fullnameOverride: webhook-gateway

image:
  repository: <your-registry>/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: oauth2
  SECURITY_OAUTH2_BASESERVERURL: https://keycloak.example.com/auth

  # Redis
  SPRING_REDIS_HOST: redis-master

  # SpiceDB
  FLOWX_SPICEDB_HOST: spicedb
  FLOWX_SPICEDB_PORT: 50051

# Secrets configuration
extraEnvVarsMultipleSecretsCustomKeys:
  - name: postgresql-generic
    secrets:
      SPRING_DATASOURCE_PASSWORD: postgresql-password-key
  - name: redis-generic
    secrets:
      SPRING_REDIS_PASSWORD: redis-password
  - 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"
```

<Info>
  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.
</Info>

### 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`           |
| Redis                | Caching                         | `flowx.ai/egress-s-redis`                |
| 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={"system"}
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

<Check>
  The Webhook Gateway pod is running and healthy: `kubectl get pods -l app=webhook-gateway`
</Check>

<Check>
  The health endpoint returns HTTP 200: `curl http://webhook-gateway:8080/actuator/health`
</Check>

<Check>
  Database migrations completed successfully — check pod logs for `Liquibase: Update has been successful`
</Check>

<Check>
  SpiceDB connection is established — check pod logs for successful CAS client initialization
</Check>

<Check>
  The `/webhooks` ingress path is accessible from external systems
</Check>

***

## 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_ALLOW_ORIGIN` | 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](./ingress-configuration).

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="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>

  <Accordion title="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>

  <Accordion title="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>

  <Accordion title="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>

  <Accordion title="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`
  </Accordion>
</AccordionGroup>

***

## Related resources

<CardGroup cols={2}>
  <Card title="Redis Configuration" icon="database" href="./redis-configuration">
    Complete Redis setup including Sentinel and Cluster modes
  </Card>

  <Card title="SpiceDB Configuration" icon="shield-halved" href="./spicedb">
    Fine-grained authorization setup
  </Card>

  <Card title="Kafka Authentication" icon="lock" href="./kafka-authentication-config">
    Configure Kafka security and authentication
  </Card>

  <Card title="IAM Configuration" icon="key" href="./access-management/configuring-an-iam-solution">
    Identity and access management setup
  </Card>
</CardGroup>
