Skip to content

Future Enhancements

Potential future enhancements that have been considered but not yet implemented. These are ideas for future development—not commitments or guarantees.


JMS-Compatible Systems (Low Effort)

These systems provide JMS client libraries that can be integrated with minimal effort since KETE already has a fully functional JMS-based destination (Amqp1Destination). The existing code uses standard jakarta.jms.* interfaces—only the ConnectionFactory implementation differs per system.

Why These Are Easy Wins

The current Amqp1Destination code is pure JMS. Adding these would only require:

  1. A new *DestinationConfig class with the system-specific ConnectionFactory
  2. Adding the client library dependency to pom.xml (with shade relocation)
  3. Documentation and quick-start examples

Amazon SQS via JMS (sqs-jms)

Amazon provides a JMS 2.0 client library for SQS, making integration straightforward.

Priority: 🥇 High (AWS market dominance)

Potential Configuration:

kete.routes.sqs.destination.kind=sqs-jms
kete.routes.sqs.destination.region=us-east-1
kete.routes.sqs.destination.queue=keycloak-events
# Optional for FIFO queues
kete.routes.sqs.destination.message-group-id=${realm}
# Authentication via environment variables or IAM role

ConnectionFactory:

import com.amazon.sqs.javamessaging.SQSConnectionFactory;

connectionFactory = new SQSConnectionFactory(
    new ProviderConfiguration(),
    SqsClient.builder().region(Region.of(region)).build()
);

Dependencies Required: - com.amazonaws:amazon-sqs-java-messaging-lib - software.amazon.awssdk:sqs

Authentication Options: - Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) - IAM instance profile (EC2/ECS) - IRSA (EKS) - Web Identity Token


Apache Pulsar via JMS (pulsar-jms)

DataStax provides a JMS 2.0 client for Apache Pulsar.

Priority: 🥈 Medium (growing adoption)

Potential Configuration:

kete.routes.pulsar.destination.kind=pulsar-jms
kete.routes.pulsar.destination.service-url=pulsar://localhost:6650
kete.routes.pulsar.destination.topic=keycloak-events
kete.routes.pulsar.destination.namespace=public/default

ConnectionFactory:

import com.datastax.oss.pulsar.jms.PulsarConnectionFactory;

Map<String, Object> config = Map.of("brokerServiceUrl", serviceUrl);
connectionFactory = new PulsarConnectionFactory(config);

Dependencies Required: - com.datastax.oss:pulsar-jms


IBM MQ (ibm-mq-jms)

IBM MQ has native JMS support—it's one of the original JMS implementations.

Priority: 🥉 Medium (enterprise legacy systems)

Potential Configuration:

kete.routes.ibm.destination.kind=ibm-mq-jms
kete.routes.ibm.destination.host=mq.example.com
kete.routes.ibm.destination.port=1414
kete.routes.ibm.destination.queue-manager=QM1
kete.routes.ibm.destination.channel=DEV.APP.SVRCONN
kete.routes.ibm.destination.queue=KEYCLOAK.EVENTS
kete.routes.ibm.destination.username=app
kete.routes.ibm.destination.password=secret

ConnectionFactory:

import com.ibm.mq.jms.MQConnectionFactory;
import com.ibm.msg.client.wmq.WMQConstants;

var factory = new MQConnectionFactory();
factory.setHostName(host);
factory.setPort(port);
factory.setQueueManager(queueManager);
factory.setChannel(channel);
factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
connectionFactory = factory;

Dependencies Required: - com.ibm.mq:com.ibm.mq.allclient


ActiveMQ Classic (activemq-classic-jms)

Apache ActiveMQ "Classic" (5.x) uses OpenWire protocol with native JMS.

Priority: Low (most users should migrate to Artemis/AMQP 1.0)

Potential Configuration:

kete.routes.amq.destination.kind=activemq-classic-jms
kete.routes.amq.destination.broker-url=tcp://localhost:61616
kete.routes.amq.destination.queue=keycloak-events
kete.routes.amq.destination.username=admin
kete.routes.amq.destination.password=admin

ConnectionFactory:

import org.apache.activemq.ActiveMQConnectionFactory;

connectionFactory = new ActiveMQConnectionFactory(brokerUrl);

Dependencies Required: - org.apache.activemq:activemq-client

Note

ActiveMQ Artemis already works via AMQP 1.0 using the existing amqp-1 destination with Qpid JMS. This would only be needed for legacy OpenWire-only deployments.


Solace PubSub+ (solace-jms)

Solace provides a JMS API for their PubSub+ platform.

Priority: Low (niche enterprise)

Potential Configuration:

kete.routes.solace.destination.kind=solace-jms
kete.routes.solace.destination.host=solace.example.com
kete.routes.solace.destination.vpn=default
kete.routes.solace.destination.queue=keycloak-events
kete.routes.solace.destination.username=admin
kete.routes.solace.destination.password=admin

Dependencies Required: - com.solacesystems:sol-jms


TIBCO EMS (tibco-ems-jms)

TIBCO Enterprise Message Service with native JMS.

Priority: Low (legacy enterprise)

Potential Configuration:

kete.routes.tibco.destination.kind=tibco-ems-jms
kete.routes.tibco.destination.server-url=tcp://localhost:7222
kete.routes.tibco.destination.queue=keycloak.events
kete.routes.tibco.destination.username=admin
kete.routes.tibco.destination.password=admin

Dependencies Required: - com.tibco:tibjms (proprietary, not in Maven Central)


Protocol-Based Destinations (One Client, Many Brokers)

These destinations use open standard protocols, providing wide broker compatibility with a single client library—similar to how KETE's amqp-1 destination works with any AMQP 1.0 broker.

SignalR (signalr)

Stream events to Microsoft SignalR hubs for real-time web applications.

Priority: Medium (Microsoft ecosystem, ASP.NET applications)

Protocol: SignalR (WebSocket-based with fallbacks)

Compatible Systems:

System Notes
Azure SignalR Service Managed SignalR in Azure
Self-hosted SignalR ASP.NET Core apps
Blazor Server Real-time Blazor applications

Potential Configuration:

kete.routes.signalr.destination.kind=signalr
kete.routes.signalr.destination.hub-url=https://app.example.com/eventshub
kete.routes.signalr.destination.method=ReceiveKeycloakEvent
kete.routes.signalr.destination.access-token=...

Dependencies Required: - com.microsoft.signalr:signalr (official Java client)

Use Cases: - Real-time dashboards showing login activity - Live user session monitoring - Browser-based admin consoles


Cloud Destinations (Native SDK Required)

Google Cloud Pub/Sub (gcp-pubsub)

Publish events to Google Cloud Pub/Sub topics.

Potential Configuration:

kete.routes.gcp.destination.kind=gcp-pubsub
kete.routes.gcp.destination.project-id=my-gcp-project
kete.routes.gcp.destination.topic=keycloak-events
kete.routes.gcp.destination.credentials-file=/path/to/service-account.json
# Or use GOOGLE_APPLICATION_CREDENTIALS environment variable

Dependencies Required: - com.google.cloud:google-cloud-pubsub

Authentication Options: - Service account JSON key file - Workload Identity (GKE) - Application Default Credentials


AWS SNS (aws-sns)

Publish events to Amazon Simple Notification Service topics.

Potential Configuration:

kete.routes.aws.destination.kind=aws-sns
kete.routes.aws.destination.topic-arn=arn:aws:sns:us-east-1:123456789:keycloak-events
kete.routes.aws.destination.region=us-east-1
# Authentication via environment variables or IAM role
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

Dependencies Required: - software.amazon.awssdk:sns

Authentication Options: - Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) - IAM instance profile (EC2/ECS) - IRSA (EKS)


AWS SQS (aws-sqs)

Send events directly to Amazon Simple Queue Service queues.

Potential Configuration:

kete.routes.aws.destination.kind=aws-sqs
kete.routes.aws.destination.queue-url=https://sqs.us-east-1.amazonaws.com/123456789/keycloak-events
kete.routes.aws.destination.region=us-east-1
kete.routes.aws.destination.message-group-id=${realm}  # For FIFO queues

Dependencies Required: - software.amazon.awssdk:sqs


AWS Kinesis (aws-kinesis)

Stream events to Amazon Kinesis Data Streams for real-time analytics.

Potential Configuration:

kete.routes.aws.destination.kind=aws-kinesis
kete.routes.aws.destination.stream-name=keycloak-events
kete.routes.aws.destination.region=us-east-1
kete.routes.aws.destination.partition-key=${realm}

Dependencies Required: - software.amazon.awssdk:kinesis


Database Destinations

JDBC Tables (jdbc-tables)

Persist events to database tables. Useful for audit logging and compliance.

Potential Configuration:

kete.routes.db.destination.kind=jdbc-tables
kete.routes.db.destination.jdbc.url=jdbc:postgresql://localhost:5432/events
kete.routes.db.destination.jdbc.username=events_user
kete.routes.db.destination.jdbc.password=secret
kete.routes.db.destination.jdbc.driver=org.postgresql.Driver
kete.routes.db.destination.table=keycloak_events

Supported Databases: - PostgreSQL - MySQL/MariaDB - SQL Server - Oracle - H2 (testing)


JDBC Stored Procedures (jdbc-callable)

Invoke stored procedures for custom event processing.

Potential Configuration:

kete.routes.sproc.destination.kind=jdbc-callable
kete.routes.sproc.destination.jdbc.url=jdbc:sqlserver://localhost:1433;databaseName=events
kete.routes.sproc.destination.jdbc.username=events_user
kete.routes.sproc.destination.jdbc.password=secret
kete.routes.sproc.destination.jdbc.procedure=CALL usp_ProcessKeycloakEvent(?, ?, ?, ?)
# Parameters: event_id, event_type, realm, payload

Redis Pub/Sub (redis-pubsub)

Publish events to Redis channels for real-time messaging.

Priority: 🥇 High (wide adoption, simple implementation)

Compatible Systems:

System Notes
Redis Self-hosted, open-source
Redis Cloud Managed Redis by Redis Inc.
Amazon ElastiCache AWS managed Redis
Azure Cache for Redis Azure managed Redis
Google Memorystore GCP managed Redis
Upstash Serverless Redis
KeyDB Redis-compatible, multi-threaded
Dragonfly Redis-compatible, high-performance

Potential Configuration:

kete.routes.redis.destination.kind=redis-pubsub
kete.routes.redis.destination.host=redis.example.com
kete.routes.redis.destination.port=6379
kete.routes.redis.destination.channel=keycloak-events
kete.routes.redis.destination.password=secret

Dependencies Required: - io.lettuce:lettuce-core or redis.clients:jedis


Redis Streams (redis-streams)

Append events to Redis Streams for persistent, ordered messaging.

Priority: 🥇 High (persistent messaging with consumer groups)

Compatible Systems: Same as Redis Pub/Sub above.

Potential Configuration:

kete.routes.redis.destination.kind=redis-streams
kete.routes.redis.destination.host=redis.example.com
kete.routes.redis.destination.port=6379
kete.routes.redis.destination.stream=keycloak-events
kete.routes.redis.destination.max-len=100000  # Trim to max entries

NATS (nats)

Publish events to NATS subjects for lightweight messaging.

Priority: 🥈 Medium (simple, fast, growing adoption)

Compatible Systems:

System Notes
NATS Server Open-source, lightweight
NATS JetStream Persistent streaming layer
Synadia Cloud Managed NATS
Synadia NGS Global NATS service

Potential Configuration:

kete.routes.nats.destination.kind=nats
kete.routes.nats.destination.servers=nats://localhost:4222
kete.routes.nats.destination.subject=keycloak.events
kete.routes.nats.destination.username=user
kete.routes.nats.destination.password=secret

Dependencies Required: - io.nats:jnats


NATS JetStream (nats-jetstream)

Publish events to NATS JetStream for persistent messaging with replay and consumer groups.

Priority: 🥈 Medium (persistent layer for NATS)

Potential Configuration:

kete.routes.nats.destination.kind=nats-jetstream
kete.routes.nats.destination.servers=nats://localhost:4222
kete.routes.nats.destination.stream=KEYCLOAK
kete.routes.nats.destination.subject=keycloak.events

Dependencies Required: - io.nats:jnats


Apache Pulsar Native (pulsar-native)

Publish events to Apache Pulsar topics using the native Pulsar client (alternative to JMS wrapper).

Priority: 🥉 Low (JMS wrapper preferred, see pulsar-jms above)

Compatible Systems:

System Notes
Apache Pulsar Self-hosted
StreamNative Cloud Managed Pulsar
DataStax Astra Streaming Managed Pulsar

Potential Configuration:

kete.routes.pulsar.destination.kind=pulsar-native
kete.routes.pulsar.destination.service-url=pulsar://localhost:6650
kete.routes.pulsar.destination.topic=persistent://public/default/keycloak-events
kete.routes.pulsar.destination.auth-plugin=org.apache.pulsar.client.impl.auth.AuthenticationToken
kete.routes.pulsar.destination.auth-params=token:xxx

Dependencies Required: - org.apache.pulsar:pulsar-client

Note

Consider using pulsar-jms instead (see JMS-Compatible Systems above) for simpler integration with existing KETE JMS infrastructure.


Additional Serializers

Avro (avro)

Serialize events using Apache Avro with Schema Registry support.

Potential Configuration:

kete.routes.avro.serializer.kind=avro
kete.routes.avro.serializer.schema-registry-url=http://schema-registry:8081
kete.routes.avro.serializer.auto-register-schemas=true

Dependencies Required: - org.apache.avro:avro - io.confluent:kafka-avro-serializer

Use Cases: - Kafka consumers requiring Avro format - Schema evolution and compatibility


Protocol Buffers (protobuf)

Serialize events using Google Protocol Buffers.

Potential Configuration:

kete.routes.proto.serializer.kind=protobuf
kete.routes.proto.serializer.schema-file=/path/to/event.proto

Dependencies Required: - com.google.protobuf:protobuf-java

Use Cases: - gRPC-based consumers - Size-efficient binary format


Logging & Observability Destinations

Syslog (syslog)

Stream events to Syslog-compatible log aggregators using RFC 5424.

Priority: 🥇 High (wide enterprise adoption, low implementation effort)

Protocol: Syslog RFC 5424 over UDP/TCP/TLS

Compatible Systems:

System Notes
rsyslog Linux default, high-performance
syslog-ng Enterprise syslog with advanced routing
Graylog Log management with syslog input
Splunk Via syslog input or HEC
Elastic/Logstash Via syslog input plugin
Papertrail Managed cloud logging
Datadog Log ingestion via syslog
Sumo Logic Cloud SIEM with syslog
Loggly Cloud log management
Fluentd/Fluent Bit Via syslog input

Potential Configuration:

kete.routes.syslog.destination.kind=syslog
kete.routes.syslog.destination.host=syslog.example.com
kete.routes.syslog.destination.port=514
kete.routes.syslog.destination.protocol=udp  # udp, tcp, or tls
kete.routes.syslog.destination.facility=local0
kete.routes.syslog.destination.severity=info
kete.routes.syslog.destination.app-name=keycloak

Dependencies Required: - com.cloudbees:syslog-java-client or custom RFC 5424 implementation

Why This Matters: - Nearly universal enterprise adoption - Simple protocol (text-based, like STOMP) - Integrates with existing log infrastructure - Low implementation effort


Real-Time Streaming Destinations

Server-Sent Events (sse)

Stream events to clients via HTTP Server-Sent Events.

Priority: 🥈 Medium (browser-friendly, simple implementation)

Protocol: SSE (HTTP streaming, text/event-stream)

Compatible Systems:

System Notes
Browsers Native EventSource API
curl curl -N for streaming
Real-time dashboards React, Vue, Angular apps
API Gateways Kong, AWS API Gateway
Mobile apps iOS/Android SSE clients

Potential Configuration:

kete.routes.sse.destination.kind=sse
kete.routes.sse.destination.url=http://dashboard.example.com/events
kete.routes.sse.destination.event-type=keycloak-event
kete.routes.sse.destination.retry=3000

Implementation Notes: - KETE acts as SSE publisher to an endpoint - Can be used with an SSE relay/fanout server - Simpler than WebSocket (unidirectional)

Use Cases: - Live admin dashboards - Real-time audit displays - Browser-based monitoring


gRPC Streaming (grpc)

Stream events to gRPC servers using bidirectional or server streaming.

Priority: 🥉 Low (high effort, niche use case)

Protocol: gRPC over HTTP/2

Compatible Systems:

System Notes
Custom gRPC servers Any language with gRPC support
Envoy Proxy gRPC routing and load balancing
Google Cloud Run Serverless gRPC
Kubernetes services Native gRPC support
Istio Service mesh with gRPC

Potential Configuration:

kete.routes.grpc.destination.kind=grpc
kete.routes.grpc.destination.target=grpc-server.example.com:9090
kete.routes.grpc.destination.service=keycloak.EventService
kete.routes.grpc.destination.method=StreamEvents
kete.routes.grpc.destination.tls.enabled=true

Dependencies Required: - io.grpc:grpc-netty-shaded - io.grpc:grpc-protobuf - io.grpc:grpc-stub - Protobuf schema for events

Implementation Notes: - Requires defining a .proto schema for Keycloak events - Higher complexity than HTTP/WebSocket - Best for microservices architectures already using gRPC


Notes

These enhancements are ideas for future development based on common use cases. Implementation priority depends on:

  1. Community demand
  2. Contributor availability
  3. Complexity vs. value
  4. Existing workarounds (e.g., Azure Service Bus works via AMQP 1.0)

Implementation Strategy

JMS-Compatible Systems are the easiest to add because:

  • KETE's Amqp1Destination already uses pure JMS code (jakarta.jms.*)
  • Only the ConnectionFactory instantiation differs per system
  • All JMS message handling, session management, and resource cleanup is reusable
  • Could be refactored into a base JmsDestination class if multiple JMS systems are added

Native SDK Destinations require more effort because:

  • Each cloud provider has unique SDK patterns
  • Authentication mechanisms vary significantly
  • No code reuse between implementations

Some destinations may never be implemented if the existing destinations provide adequate coverage through protocol compatibility (e.g., ActiveMQ Artemis via AMQP 1.0).