get_ip_activity
Exhaustively investigate all activity from a specific source IP address. Fully paginates each requested event type over a date range for a complete picture of brute-force or shared-workstation incidents.
Instructions
Exhaustive investigation of all activity from one source IP address.
Unlike get_events(ip_address=...), which filters a single page and can
miss activity outside the most recent max_results events, this tool
fully paginates every requested event type (via get_events_all) before
filtering by IP, so the result is exhaustive over the requested date
range. Use this for brute-force / credential-stuffing / shared-workstation
investigations where get_login_failures_by_ip told you which IP to
look at and you now need the full picture for that one IP.
Returns a fixed-shape dict (JSON), not formatted text — every key below is always present, even when zero events match.
Returns: error: None on success. Set to a descriptive message if event_types resolved to no event types (e.g. empty or all-whitespace/commas); every other key is still present, with an empty/zero result in that case (no data was fetched). ip_address: Echoes the input. site: Site name from KEYCLOAK_SITES_INI, or null if unmatched or unconfigured (see sites_configured to tell those apart). sites_configured: True if KEYCLOAK_SITES_INI was loaded at all. date_from / date_to: The resolved date range actually scanned. event_types: The event types scanned (echoes the input, split). summary: total_events, login_success, login_failure, unique_users, unique_clients, first_seen/last_seen (ISO 8601, null if no match). login_success/login_failure classify EVERY scanned event type by whether its type ends in "_ERROR" (matching the users/clients breakdown below), not just literal LOGIN/LOGIN_ERROR — so widening event_types always keeps these numbers reconciled with the per-user/per-client totals. Always computed over the FULL matched set, unaffected by max_timeline truncation. users: Per-user breakdown (success/failure counts, distinct error codes), sorted by total activity descending. Note: successful LOGIN events often carry only a userId (UUID) while LOGIN_ERROR carries details.username — this tool keys on username-or-userId-or-"unknown", so the same human can legitimately appear under two different keys across success vs. failure events. clients: Per-client (SP) breakdown, same shape, sorted descending. timeline: Chronological event list, capped at max_timeline (most recent kept on overflow — see truncated). max_timeline<=0 returns an empty timeline. truncated: True if timeline was capped; summary/users/clients are never affected by this cap.
Args: ip_address: Source IP to investigate. Compared against KeyCloak's recorded ipAddress field after normalizing both sides through Python's ipaddress module (so equivalent IPv6 notations like "::1" and "0:0:0:0:0:0:0:1" match); falls back to a raw string compare if either side doesn't parse as an IP. event_types: Comma-separated KeyCloak event types to scan (default "LOGIN,LOGIN_ERROR"). Widen with e.g. "LOGIN,LOGIN_ERROR,LOGOUT,UPDATE_PASSWORD,CLIENT_LOGIN,CLIENT_LOGIN_ERROR" for a broader sweep. Must resolve to at least one type. date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). Widening the window means fully paginating every event type over that window before filtering — expect it to be slower on large realms. date_to: End date (YYYY-MM-DD). Empty for open-ended. max_timeline: Cap on the number of most-recent timeline entries returned (default 200; <=0 means no timeline entries). Does not affect summary/users/clients.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| date_from | No | ||
| ip_address | Yes | ||
| event_types | No | LOGIN,LOGIN_ERROR | |
| max_timeline | No |