Recording and auditing activity in Keycloak: login and admin event types, event listeners, storage and retention configuration, and using events for security monitoring.

In episode 21 you decorated Keycloak with custom themes. Episode 22 is about the trail: events & auditing. Keycloak records what happens — who logged in, who failed to log in, what admins changed — and it becomes the raw material for investigations, compliance, and monitoring. This episode also completes the least privilege principle from episode 18: without records, you don't know whether permissions are actually being used.
The Events tab in the admin console splits records into two large groups: user events and admin events.
| Category | Example events | Recorded as |
|---|---|---|
| Login events | LOGIN, LOGOUT, REFRESH_TOKEN | User events |
| Token events | CODE_TO_TOKEN, REFRESH_TOKEN | User events |
| Registration | REGISTER | User events |
| Account activity | UPDATE_PASSWORD, VERIFY_EMAIL | User events |
| Error events | LOGIN_ERROR, REGISTER_ERROR | User events |
| Admin actions | create user, delete client, change realm | Admin events |
An example of a stored event record:
{
"type": "LOGIN",
"realmId": "myrealm",
"clientId": "webapp",
"userId": "6f1a0c1e-0000-0000-0000-000000000001",
"ipAddress": "203.0.113.10",
"time": 1764800000000,
"details": {
"auth_method": "openid-connect"
}
}Distinguishing user events from admin events is important: user events describe the end-user experience, while admin events are the accountability of the people holding the console.
Events that occur are delivered to listeners. Keycloak provides several built-in listeners and opens a path for custom ones:
| Listener | Function |
|---|---|
| JBoss logging | Writes events to the server log |
| JPA (database event storage) | Stores events in database tables |
| Custom listener | Own SPI implementation, e.g. sending to a webhook |
| External integration | Forwarding to a SIEM or monitoring system |
Listeners are enabled in Realm Settings → Events → the Config tab, in the Event listeners column. If no listener is active, events still happen but leave no trace — make sure at least logging is active.
Check Save events so events are stored in the database and searchable, and Save admin events for records of admin actions. Without these, events only pass through listeners at that moment and are lost.
Set the Expiration for events — how long records are kept before being cleaned up. Long retention is good for auditing, but burdens storage; adjust to your compliance needs.
The User events tab provides filters: event type, client, user, and date range. These queries are what you use during incident investigation, for example "who failed to log in from this IP".
You can choose which event types are recorded and which are ignored. Filtering helps control volume, but be careful: being too aggressive can erase evidence when you need it.
Complete records and clear retention are the raw material for compliance reporting: showing who signed in, when, and what admins did. Combine with data export from event queries for periodic reports.
If you use database event storage (JPA), events are stored in tables that can be accessed directly. Direct queries are useful for periodic reports not available in the admin console interface.
SELECT type, client_id, ip_address, time
FROM event_entity
WHERE realm_id = 'myrealm'
AND type IN ('LOGIN', 'LOGIN_ERROR')
ORDER BY time DESC
LIMIT 50;Table names vary between releases — check the documentation for the version you use. What matters to understand: reading events directly from the database gives full flexibility for reports, while the admin console interface is enough for quick investigations.
Tip
Don't put logs containing sensitive session details somewhere anyone can access. Record events with a sensible retention and restrict access to event data to authorized teams only.
Events are the raw material for monitoring. The most useful patterns:
LOGIN_ERROR in a short time can mean brute force.For automatic metrics, enable the Keycloak metrics endpoint:
bin/kc.sh start --metrics-enabled true --health-enabled trueWith metrics-enabled Keycloak provides a metrics endpoint that can be scraped by Prometheus, while health-enabled provides health checks. Run kc.sh start --metrics-enabled in your environment to see it.
In episode 22, you understood events and auditing in Keycloak: event types (login, token, registration, error, admin), event listeners (JBoss logging, database storage, custom, external integration), audit configuration (retention, queries, filtering, compliance), and event-based monitoring.
Key takeaways:
Save events — without it there's no trail to investigate.LOGIN_ERROR is an early attack signal — watch it from the monitoring side.In the next episode (episode 23), you'll raise the security level of login: Multi-Factor Authentication (MFA) — OTP, WebAuthn, SMS, and recovery codes.