HTTP Destination¶
Stream Keycloak events to HTTP/REST endpoints.
| Property | Value |
|---|---|
destination.kind |
http |
| Protocol | HTTP/HTTPS |
Compatible Systems¶
| System | Notes |
|---|---|
| Any REST API | POST/PUT to any HTTP endpoint |
| Webhooks | Slack, Discord, Teams, PagerDuty, etc. |
| API Gateways | Kong, AWS API Gateway, Azure APIM |
| Cloud Functions | AWS Lambda URLs, Azure Functions, Cloud Run |
| Custom backends | Any HTTP-accessible service |
Example Configurations¶
kete.routes.oauth-api.realm-matchers.realm=list:master
kete.routes.oauth-api.destination.kind=http
kete.routes.oauth-api.destination.url=https://api.example.com/api/v1/events
kete.routes.oauth-api.destination.oauth.enabled=true
kete.routes.oauth-api.destination.oauth.token-url=https://auth.example.com/oauth/token
kete.routes.oauth-api.destination.oauth.client-id=keycloak-client
kete.routes.oauth-api.destination.oauth.client-secret=secret
kete.routes.oauth-api.destination.oauth.scope=events:write
# Uses Keycloak itself as OAuth server - auto-creates client!
kete.routes.internal-oauth.realm-matchers.realm=list:master
kete.routes.internal-oauth.destination.kind=http
kete.routes.internal-oauth.destination.url=https://api.example.com/api/events
kete.routes.internal-oauth.destination.oauth.enabled=true
kete.routes.internal-oauth.destination.oauth.mode=internal
Features¶
- Automatic retry with exponential backoff
- OAuth 2.0 Client Credentials with token caching
- Custom headers and configurable timeouts
- TLS/SSL with mTLS support
Configuration Properties¶
Required Properties¶
| Property | Description | Example |
|---|---|---|
destination.kind |
Must be http |
http |
destination.url |
Full URL (supports templating) | https://api.example.com:8443/events/${realmLowerCase} |
Dynamic URLs (Templating)¶
The url property supports template variables:
# Dynamic URL per realm
kete.routes.webhook.destination.url=https://api.example.com/events/${realmLowerCase}
# Dynamic URL with event type
kete.routes.webhook.destination.url=https://api.example.com/${kindLowerCase}/${eventTypeLowerCase}
Available variables: ${realmLowerCase}, ${realmUpperCase}, ${eventTypeLowerCase}, ${eventTypeUpperCase}, ${kindLowerCase}, ${kindUpperCase}, ${resourceTypeLowerCase}, ${resourceTypeUpperCase}, ${operationTypeLowerCase}, ${operationTypeUpperCase}, ${resultLowerCase}, ${resultUpperCase}
When using destination.url:
- The host is extracted from the URL
- The port defaults to 80 for http, 443 for https
- The path and query string are extracted
- TLS is auto-enabled when the scheme is
https
If both url and individual properties are specified, url takes precedence.
Alternative: Individual Properties¶
Instead of url, you can configure each component separately:
| Property | Description | Example |
|---|---|---|
destination.host |
Target HTTP host (required if no url) |
api.example.com |
Optional Properties¶
| Property | Default | Description | Example |
|---|---|---|---|
destination.port |
80 (HTTP) / 443 (HTTPS) |
HTTP port | 8080 |
destination.path-and-query |
/ |
URL path and query string | /api/v1/events?source=keycloak |
destination.method |
POST |
HTTP method (POST or PUT) | PUT |
destination.timeout-seconds |
10 |
Request timeout in seconds | 60 |
destination.pool.min-idle |
1 |
Minimum idle connections in pool | 5 |
destination.pool.max-idle |
10 |
Maximum idle connections in pool | 20 |
destination.pool.max-total |
20 |
Maximum total connections in pool | 50 |
Custom Headers¶
Headers are configured under destination.headers.<NAME>:
kete.routes.my-api.destination.headers.X-API-Key=my-secret-key
kete.routes.my-api.destination.headers.X-Source=keycloak
OAuth 2.0 Properties¶
The HTTP destination supports two OAuth modes:
External Mode (Default)¶
Use an external OAuth 2.0 authorization server:
| Property | Required | Default | Description |
|---|---|---|---|
destination.oauth.enabled |
No | false |
Enable OAuth 2.0 Client Credentials flow |
destination.oauth.mode |
No | external |
OAuth mode: external or internal |
destination.oauth.token-url |
Yes* | - | OAuth token endpoint URL |
destination.oauth.client-id |
Yes* | - | OAuth client ID |
destination.oauth.client-secret |
Yes* | - | OAuth client secret |
destination.oauth.scope |
No | "" |
Requested OAuth scopes (space-separated) |
*Required when oauth.enabled=true and oauth.mode=external.
Internal Mode¶
Use the current Keycloak instance as the OAuth server. This mode automatically registers a service account client in Keycloak during initialization - the simplest setup possible:
| Property | Required | Default | Description |
|---|---|---|---|
destination.oauth.enabled |
Yes | false |
Enable OAuth 2.0 |
destination.oauth.mode |
Yes | - | Must be internal |
destination.oauth.realm |
No | Route realm | Override realm for token URL |
destination.oauth.client-id |
No | kete-oauth-client |
Override auto-generated client ID |
destination.oauth.client-secret |
No | Auto-generated | Override auto-generated secret |
destination.oauth.scope |
No | "" |
Requested OAuth scopes |
Internal Mode Example:
# Simplest OAuth setup - just 2 properties!
kete.routes.api.destination.oauth.enabled=true
kete.routes.api.destination.oauth.mode=internal
This automatically:
- Creates a confidential client
kete-oauth-clientin the route's realm - Enables service account (client credentials grant)
- Generates a secure client secret
- Configures the token URL for the realm
TLS Properties¶
See TLS & mTLS for full details on TLS options.
| Property | Default | Description |
|---|---|---|
destination.tls.enabled |
false |
Enable HTTPS (auto-enabled when using url with https:// scheme) |
destination.tls.key-store.* |
- | Client certificate for mTLS |
destination.tls.trust-store.* |
- | CA certificates |
Configuration Examples¶
Example 1: Simple POST Webhook¶
kete.routes.webhook.realm-matchers.realm=list:master
kete.routes.webhook.destination.kind=http
kete.routes.webhook.destination.url=https://hooks.example.com/keycloak/events
kete.routes.webhook.event-matchers.login=glob:LOGIN*
Example 2: Internal OAuth (Simplest Setup)¶
Use the current Keycloak instance for OAuth - no external auth server needed:
kete.routes.internal-oauth.realm-matchers.realm=list:master
kete.routes.internal-oauth.destination.kind=http
kete.routes.internal-oauth.destination.url=https://api.example.com/v1/events
kete.routes.internal-oauth.destination.oauth.enabled=true
kete.routes.internal-oauth.destination.oauth.mode=internal
kete.routes.internal-oauth.event-matchers.filter=glob:*
Example 3: External OAuth with Retry¶
kete.routes.api.realm-matchers.realm=list:master
kete.routes.api.destination.kind=http
kete.routes.api.destination.url=https://api.example.com/v1/events
kete.routes.api.destination.method=PUT
kete.routes.api.destination.timeout-seconds=60
kete.routes.api.destination.oauth.enabled=true
kete.routes.api.destination.oauth.mode=external
kete.routes.api.destination.oauth.token-url=https://auth.example.com/token
kete.routes.api.destination.oauth.client-id=events-publisher
kete.routes.api.destination.oauth.client-secret=your-secret-here
kete.routes.api.destination.oauth.scope=api:write
kete.routes.api.event-matchers.filter=glob:*
kete.routes.api.retry.enabled=true
kete.routes.api.retry.max-attempts=3
kete.routes.api.retry.wait-duration=PT1S
Example 4: Custom Headers with API Key¶
kete.routes.custom.realm-matchers.realm=list:master
kete.routes.custom.destination.kind=http
kete.routes.custom.destination.url=https://api.example.com/events
kete.routes.custom.destination.headers.X-API-Key=sk-1234567890
kete.routes.custom.destination.headers.X-Source=keycloak
kete.routes.custom.event-matchers.filter=glob:*
Example 5: mTLS Configuration¶
kete.routes.secure.realm-matchers.realm=list:master
kete.routes.secure.destination.kind=http
kete.routes.secure.destination.url=https://secure-api.example.com/events
kete.routes.secure.destination.tls.key-store.loader.kind=pkcs12-file-path
kete.routes.secure.destination.tls.key-store.loader.path=/certs/client.p12
kete.routes.secure.destination.tls.key-store.password=keystorepass
kete.routes.secure.destination.tls.trust-store.loader.kind=pem-file-path
kete.routes.secure.destination.tls.trust-store.loader.path=/certs/ca.pem
kete.routes.secure.event-matchers.filter=glob:*
Retry Configuration¶
Retry is configured at the route level, not within the destination. See Retry for full configuration options.
Common Integration Patterns¶
Webhook Services¶
Zapier:
kete.routes.zapier.realm-matchers.realm=list:master
kete.routes.zapier.destination.kind=http
kete.routes.zapier.destination.url=https://hooks.zapier.com/hooks/catch/123456/abcdef/
Make (Integromat):
kete.routes.make.realm-matchers.realm=list:master
kete.routes.make.destination.kind=http
kete.routes.make.destination.url=https://hook.eu1.make.com/abc123def456
Serverless Functions¶
AWS Lambda (via API Gateway):
kete.routes.lambda.realm-matchers.realm=list:master
kete.routes.lambda.destination.kind=http
kete.routes.lambda.destination.url=https://abc123.execute-api.us-east-1.amazonaws.com/prod/events
kete.routes.lambda.destination.headers.x-api-key=your-api-key
Azure Functions: