Nocode event-listener in Keycloak
An event listener in Keycloak catches all events (user events and admin events) through a method called “onEvent”
void onEvent(Event event);
With an implementation, you can trigger a custom process. For example, call a webhook :
https://github.com/cevheri/keycloak-custom-event-listener
At please-open.it we love n8n for all automation tasks.
We also provide support of openid connect to n8n
https://please-open.it/blog/n8n-openid-client/
A “webhook” can be an entry point for an automation in n8n, so with the plugin shown previously you can call this webhook when an event occurs in Keycloak.
With this method, you have to maintain and deploy a custom event listener. Can we make something simpler ? YES !
In your realm configuration, under the “events” tab you can save all user (or admin) events in Keycloak database. Be careful with this feature, it creates a line in the “event_entity” table each time an event is saved.
Of course, do not forget to add an expiration that cleans the table.
n8n has the ability to listen for an “insert” in a postgres table.
So, each time an event is saved in the postgres database, the workflow is triggered. Without any custom SPI in Keycloak !
The event looks like :
What we have from Keycloak is :
"payload":
{
"id": "55638351-37bb-4da9-be76-46ca5c0af790",
"client_id": "security-admin-console",
"details_json": null,
"error": null,
"ip_address": "92.184.110.123",
"realm_id": "b3d0c91f-3091-4afb-8dfa-04a15832e42e",
"session_id": "ca026ecf-189b-4100-96d6-53d28ce07d2c",
"event_time": 1732091485233,
"type": "LOGOUT",
"user_id": "be398e07-55b3-4a8c-b4e4-e26d006b057d",
"details_json_long_value": "{"redirect_uri":"https://mcwfbjaukwiwmwljrsjf-keycloak.services.clever-cloud.com/admin/master/console/#/master/realm-settings/events"}"
}
Create a new client in Keycloak, dedicated to n8n with only “service account” enabled :
Then, add some capabilities under “service account roles” tab :
Create a new HTTP Post request in n8n for authentication :
with :
- client_id
- client_secret
- grant_type=client_credentials
ok, you have an access_token.
A new HTTP request to the admin API. Do not forget the access_token got previously.
And my user is …
[
{
"id": "be398e07-55b3-4a8c-b4e4-e26d006b057d",
"username": "cc-account-admin",
"emailVerified": false,
"enabled": true,
"totp": false,
"disableableCredentialTypes": [],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": false,
"manage": true
}
}
]
This implementation comes from a common use case : replicate users in a CRM. We have been using this method for a while now, debugging and maintenance are way simpler than a custom event listener.