get_ip_activity
Exhaustively retrieve and analyze all events from a single source IP address over a date range, providing a summary, per-user/per-client breakdown, and timeline for security investigations.
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.
events_capped: True if event pagination itself was cut short by the
wall-clock deadline (KEYCLOAK_DEADLINE) or the per-type cap
(KEYCLOAK_MAX_EVENTS) — i.e. the window was too wide and the WHOLE
result (summary/users/clients/timeline) is incomplete. Distinct from
truncated, which only trims the timeline of an otherwise-complete
scan. Narrow date_from when this is true.
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 |