Panther high experimental python

Okta AD Agent Token Abuse - Behavioral

Detects potential Okta AD Agent token theft and abuse using behavioral analysis. Instead of relying on hardcoded service account patterns, this detection identifies when AD agent-related activities (API token creation, agent registration, config changes) occur from previously unseen IP addresses or user agents. This behavioral approach adapts to your environment and catches anomalous access patterns that may indicate compromised credentials or unauthorized token generation. **What This Detection Catches:** - API token creation from new IPs or user agents - New AD agent registrations from unexpected sources - AD agent configuration changes from new locations **Complementary Detection:** Use alongside `Okta.ADAgent.AuthenticationAnomaly.ZScore` which detects the actual USE of stolen tokens through authentication pattern anomalies.

View Source

Detection Logic

def rule(event):
    # Query already filtered for anomalies.
    # Guard against malformed rows missing the primary key field.
    return bool(event.get("actorId"))


def title(event):
    actor = event.get("actorId", "<UNKNOWN_ACTOR>")
    event_type = event.get("eventType", "<UNKNOWN_EVENT>")
    anomaly_type = event.get("anomaly_type", "Unknown Anomaly")

    return f"Okta AD Agent Activity from {anomaly_type}: {actor} - {event_type}"


def severity(event):
    event_type = event.get("eventType", "")

    # New agent registration is critical (potential rogue agent)
    if "agent_instance_added" in event_type:
        return "CRITICAL"

    # Token creation from new source is high severity
    if "api_token.create" in event_type:
        return "HIGH"

    # Config changes are medium severity
    if "config_change" in event_type:
        return "MEDIUM"

    return "MEDIUM"


def dedup_key(event):
    actor = event.get("actorId", "unknown")
    event_date = str(event.get("p_event_time", "unknown"))[:10]
    return f"okta_ad_agent_token_abuse_{actor}_{event_date}"


def alert_context(event):
    return {
        "actor_id": event.get("actorId", "<UNKNOWN_ACTORID>"),
        "actor_name": event.get("actorName", "<UNKNOWN_ACTORNAME>"),
        "event_type": event.get("eventType", "<UNKNOWN_EVENTTYPE>"),
        "source_ip": event.get("sourceIP", "<UNKNOWN_SOURCEIP>"),
        "user_agent": event.get("userAgent", "<UNKNOWN_USERAGENT>"),
        "anomaly_type": event.get("anomaly_type", "<UNKNOWN_ANOMALYTYPE>"),
        "target": event.get("target", []),
        "event_time": event.get("p_event_time", "<UNKNOWN_EVENTTIME>"),
    }

Field Validations

Loading…

Comments (0)

Loading comments...