Consumer Model
Summary
The Consumer Model defines how downstream services register to receive platform events through Integration Hub. The Subscription Management service maintains a registry of event type definitions and subscriber registrations. Each subscription maps a specific event key (sourceService + eventType + resourceType + operationType) to a delivery endpoint with authentication credentials. The service exposes both gRPC and REST APIs for CRUD operations. During event processing, the Event Processor queries this registry via gRPC to resolve active subscriptions for each incoming event.
Why It Exists
Without a centralized subscription registry:
- Event routing would be hardcoded — Adding or removing a subscriber would require code changes and redeployment of the Event Processor
- Authentication management would be scattered — Each subscriber's credentials would need to be managed in configuration files across services
- Visibility would be limited — Operators would have no single place to inspect which services receive which events
The Subscription Management service provides a dynamic, API-driven registry that decouples subscriber configuration from the event processing pipeline.
Where It Fits in Keymate
The Consumer Model is the configuration layer of the Integration Hub pipeline. The Event Processor queries this model via gRPC during routing. The delivery configuration stored here (endpoint, auth, protocol) is embedded into each OutboxEvent envelope and used by the Outbox Processor for HTTP delivery.
Boundaries
In scope:
- Event type definition CRUD
- Subscription registration CRUD
- Authentication configuration per subscription
- gRPC and REST API surfaces
- Database schema
Out of scope:
- Event ingestion → gRPC Ingestion Surface
- Topic routing → Producer Model
- HTTP delivery → Connector & Delivery Model
How It Works
Data Model
The subscription registry has two entities with a one-to-many relationship:
Event Types
Defines the event keys that subscribers can register for. Each event type is uniquely identified by the combination of sourceService, eventType, resourceType, and operationType.
Subscriptions
Registers a subscriber for a specific event type. Each subscription specifies:
| Field | Description |
|---|---|
| Subscriber service | Name identifying the subscribing service |
| Delivery endpoint | Target URL for event delivery |
| Callback protocol | Delivery protocol (HTTP, GRPC, etc.) |
| Active | Whether the subscription is active (default: true) |
| Auth | Authentication credentials (see Authentication Types below) |
| Payload type | Payload format (JSON, PROTOBUF, etc.) |
Deleting an event type automatically cascades to all associated subscriptions.
Authentication Types
The auth JSONB field stores credentials matching one of the supported types:
| Auth Type | Required Fields | Description |
|---|---|---|
BASIC | username, password | HTTP Basic Authentication |
OAUTH2 | client_id, client_secret, token_url, scope | OAuth 2.0 client credentials flow |
JWT | token | Pre-shared JWT in Authorization header |
APIKEY | key, header_name | API key in a configurable header (e.g., X-API-KEY) |
Unspecified authentication types are rejected during validation.
gRPC API
The Subscription Management gRPC service exposes the following methods:
Subscription operations:
| Method | Request | Response | Description |
|---|---|---|---|
GetAllSubscriptions | Empty | SubscriptionsResponse | List all subscriptions |
GetSubscriptionById | IdRequest | SubscriptionResponse | Get by UUID |
GetSubscriptionByEventId | IdRequest | SubscriptionsByEventResponse | Get subscriptions for an event type |
GetSubscriptionsByEvent | SubscriptionsByEventRequest | SubscriptionsByEventResponse | Lookup by event key (used by Event Processor) |
CreateSubscription | Subscription | Empty | Create |
UpdateSubscription | Subscription | Empty | Update |
DeleteSubscription | IdRequest | Empty | Delete |
Event type operations:
| Method | Request | Response | Description |
|---|---|---|---|
GetSubscriptionEvents | Empty | EventsResponse | List all event types |
GetSubscriptionEventById | IdRequest | EventResponse | Get by UUID |
CreateSubscriptionEvent | SubscriptionEvent | Empty | Register new event type |
UpdateSubscriptionEvent | SubscriptionEvent | Empty | Update |
DeleteSubscriptonEvent | IdRequest | Empty | Delete |
REST API
The Subscription Management service also exposes REST endpoints for both subscriptions and event types. Both resource types support full CRUD operations:
| Resource | Operations | Filterable Fields |
|---|---|---|
| Subscriptions | List, Get by ID, Get by event ID, Create, Update, Delete | event_id, subscriber_service, callback_protocol, request_method, active, payload_type |
| Event types | List, Get by ID, Create, Update, Delete | source_service, event_type, resource_type, operation_type |
OpenAPI documentation and Swagger UI are available at the service's standard documentation endpoints.
Subscription Resolution Flow
When the Event Processor receives an event, it calls GetSubscriptionsByEvent with a SubscriptionsByEventRequest containing the event's sourceService, eventType, resourceType, and operationType. The Subscription Management service returns all active subscriptions matching this key. This lookup is the critical connection between event ingestion and delivery routing.
Diagram
Example Scenario
Scenario
A developer registers a new subscriber endpoint to receive user creation events.
Input
- Actor: Platform developer
- Resource: Subscription Management REST API
- Action: Create event type + create subscription
- Context:
- Source:
"keycloak" - Event type:
"KEYCLOAK_ADMIN_EVENT" - Resource type:
"USER" - Operation type:
"CREATE" - Subscriber endpoint:
https://my-service.example.com/webhooks/users - Auth: OAuth2 client credentials
- Source:
Expected Outcome
- The event type definition is created via the REST API
- The subscriber is registered with endpoint, auth, and payload type via the REST API
- When a user creation event is ingested, Event Processor calls
GetSubscriptionsByEvent→ the new subscription is returned - An
OutboxEventenvelope is created with the subscriber's endpoint and auth - The event is delivered to
https://my-service.example.com/webhooks/users
Common Misunderstandings
-
"Subscriptions match on partial keys" — Subscription resolution matches on the full composite key (
sourceService+eventType+resourceType+operationType). Partial matches do not return results. -
"Deleting an event type preserves its subscriptions" — Deleting an event type automatically cascades to all associated subscriptions. All subscribers registered for that event type are removed.
-
"Inactive subscriptions still receive events" — Only subscriptions with
active = trueare returned during resolution. Settingactive = falseeffectively pauses delivery without deleting the subscription.
The auth field stores credentials in JSONB. In production, ensure that the relational database is encrypted at rest and that access to the Subscription Management API is restricted. Credentials stored in subscriptions (passwords, client secrets, API keys) are sensitive data.
Design Notes / Best Practices
-
Use specific event keys — Register event types with the most specific
(sourceService, eventType, resourceType, operationType)combination possible. Broad subscriptions increase delivery volume and subscriber processing load. -
Set
active = falseto pause delivery — Rather than deleting a subscription to temporarily stop delivery, setactive = false. This preserves the configuration for easy re-enablement. -
Use OAuth2 for service-to-service subscriptions — OAuth2 client credentials flow provides token rotation and revocation capabilities that static tokens and API keys do not offer.
The gRPC API is the recommended interface for programmatic subscription management and is used by the Event Processor for runtime resolution. The REST API is ideal for operator tooling, debugging, and manual administration.
Next Step
Continue with Event-Driven Distribution to understand how events are routed to domain-specific outbox topics and fanned out to multiple subscribers.