Detection rules › Panther

Panther rules: push

Push Security App Banner Acknowledged

#
Severity
low
Log types
PushSecurity.Activity
Source
github.com/panther-labs/panther-analysis

Detection logic

def rule(event):
    if event.get("object") != "APP_BANNER":
        return False

    if event.deep_get("new", "action") == "ACKNOWLEDGED":
        return True

    return False


def title(event):
    app_type = event.deep_get("new", "appType")
    employee_email = event.deep_get("new", "employee", "email")
    return f"{app_type} accessed by {employee_email}"


def alert_context(event):
    return {
        "Push Security app banner": event.deep_get("new", "appBanner", "mode"),
        "Title": event.deep_get("new", "appBanner", "title"),
        "Subtext": event.deep_get("new", "appBanner", "subtext"),
        "Button": event.deep_get("new", "appBanner", "buttonText"),
    }

Rule specification

AnalysisType: rule
Filename: push_security_app_banner_acknowledged.py
RuleID: "Push.Security.App.Banner.Acknowledged"
DisplayName: "Push Security App Banner Acknowledged"
Enabled: true
LogTypes:
  - PushSecurity.Activity
Severity: Low
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Activity events when all of the conditions below hold.

Condition

  • object is APP_BANNER
  • new.action is ACKNOWLEDGED

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
Push Security app bannernew.appBanner.mode
Titlenew.appBanner.title
Subtextnew.appBanner.subtext
Buttonnew.appBanner.buttonText
appTypenew.appType
emailnew.employee.email

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "c478966c-f927-411c-b919-179832d3d50c",
  "new": {
    "action": "ACKNOWLEDGED",
    "appBanner": {
      "buttonText": "Proceed anyway",
      "mode": "ACKNOWLEDGE",
      "subtext": "This app is not approved, please use Google Drive instead.",
      "title": "This app is not approved for use"
    },
    "appType": "DROPBOX",
    "browser": "CHROME",
    "employee": {
      "chatopsEnabled": true,
      "creationTimestamp": 1698669223.0,
      "department": "Security Engineering",
      "email": "john.hill@example.com",
      "firstName": "John",
      "id": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
      "lastName": "Hill",
      "licensed": true,
      "location": "New York"
    },
    "os": "WINDOWS",
    "sourceIpAddress": "8.158.25.38",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
  },
  "object": "APP_BANNER",
  "timestamp": 1698604061.0,
  "version": "1"
}

Push Security Authorized IdP Login

#
Severity
informational
Log types
PushSecurity.Activity
Tags
Configuration Required
Reference
github.com
Source
github.com/panther-labs/panther-analysis

Login to application with unauthorized identity provider which could indicate a SAMLjacking attack.

Detection logic

# Configure allowed identity provider logins to SaaS apps
allowed_idps = {
    # "GOOGLE_WORKSPACE": {"OIDC_LOGIN", "SAML_LOGIN"},
    "OKTA": {"PASSWORD_LOGIN"},
}


def rule(event):
    if event.get("object") != "LOGIN":
        return False

    identity_provider = event.deep_get("new", "identityProvider")
    login_type = event.deep_get("new", "loginType")

    if identity_provider in allowed_idps and login_type in allowed_idps[identity_provider]:
        return True
    return False


def title(event):
    identity_provider = event.deep_get("new", "identityProvider", default="Null identityProvider")
    login_type = event.deep_get("new", "loginType", default="Null loginType")
    app_type = event.deep_get("new", "appType", default="Null appType")
    new_email = event.deep_get("new", "email")

    return f"Authorized identity provider in use. User: {new_email} \
        used {identity_provider} {login_type} on {app_type}"

Rule specification

AnalysisType: rule
Filename: push_security_authorized_idp_login.py
RuleID: "Push.Security.Authorized.IdP.Login"
DisplayName: "Push Security Authorized IdP Login"
Enabled: false
CreateAlert: false
LogTypes:
  - PushSecurity.Activity
Tags:
  - Configuration Required
Severity: Info
Description: Login to application with unauthorized identity provider which could indicate a SAMLjacking attack.
DedupPeriodMinutes: 60
Threshold: 1
Reference: https://github.com/pushsecurity/saas-attacks/blob/main/techniques/samljacking/description.md
InlineFilters:
  - All: []

Stages and Predicates

Fires on PushSecurity.Activity events when all of the conditions below hold.

Condition

  • object is LOGIN
  • new.identityProvider is one of OKTA

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emailnew.email
identityProvidernew.identityProvider
loginTypenew.loginType
appTypenew.appType

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "d240e3f2-3cd6-425f-a835-dad0ff237d09",
  "new": {
    "accountId": "a93b45a7-fdce-489e-b76d-2bd6862a62ba",
    "appId": "8348ca36-d254-4e1b-8f31-6837d82fc5cb",
    "appType": "Dropbox",
    "browser": "EDGE",
    "email": "jet.black@issp.com",
    "employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
    "identityProvider": "OKTA",
    "leakedPassword": false,
    "loginTimestamp": 1707773386.0,
    "loginType": "PASSWORD_LOGIN",
    "os": "WINDOWS",
    "passwordId": "6ae9f0b2-9300-43f0-b210-c0d3c16640f8",
    "passwordManuallyTyped": false,
    "sourceIpAddress": "35.90.103.134",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.2420.81",
    "weakPassword": false,
    "weakPasswordReasons": null
  },
  "object": "LOGIN",
  "timestamp": 1707774319.0,
  "version": "1"
}

Push Security New App Detected

#
Severity
informational
Log types
PushSecurity.Entities
Source
github.com/panther-labs/panther-analysis

Detection logic

def rule(event):
    if event.get("object") != "APP":
        return False

    if event.get("type") == "CREATE":
        return True

    return False


def title(event):
    new_type = event.deep_get("new", "type")
    return f"New app in use: {new_type}"

Rule specification

AnalysisType: rule
Filename: push_security_new_app_detected.py
RuleID: "Push.Security.New.App.Detected"
DisplayName: "Push Security New App Detected"
Enabled: true
LogTypes:
  - PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Entities events when all of the conditions below hold.

Condition

  • object is APP
  • type is CREATE

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
typenew.type

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "c478966c-f927-411c-b919-179832d3d50c",
  "new": {
    "approvalStatus": null,
    "creationTimestamp": 1698064423.0,
    "id": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
    "notes": "",
    "ownerId": null,
    "sensitivityLevel": null,
    "type": "ZAPIER"
  },
  "object": "APP",
  "old": null,
  "timestamp": 1698604061.0,
  "type": "CREATE",
  "version": "1"
}

Push Security New SaaS Account Created

#
Severity
informational
Log types
PushSecurity.Entities
Source
github.com/panther-labs/panther-analysis

Detection logic

def rule(event):
    if event.get("object") != "ACCOUNT":
        return False

    if event.get("type") == "CREATE":
        return True

    return False


def title(event):
    app_type = event.deep_get("new", "appType")
    new_email = event.deep_get("new", "email")
    return f"New account on {app_type} created by {new_email}"

Rule specification

AnalysisType: rule
Filename: push_security_new_saas_account_created.py
RuleID: "Push.Security.New.SaaS.Account.Created"
DisplayName: "Push Security New SaaS Account Created"
Enabled: true
LogTypes:
  - PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Entities events when all of the conditions below hold.

Condition

  • object is ACCOUNT
  • type is CREATE

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
appTypenew.appType
emailnew.email

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "c478966c-f927-411c-b919-179832d3d50c",
  "new": {
    "appId": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
    "appType": "ATLASSIAN",
    "creationTimestamp": 1698064423.0,
    "email": "john.hill@example.com",
    "employeeId": "72d0347a-2663-4ef5-b1c5-df39163f1603",
    "id": "d6a32ba5-0532-4a66-8137-48cdf409c972",
    "lastUsedTimestamp": 1698669168.0,
    "loginMethods": {
      "oidcLogin": "GOOGLE_WORKSPACE",
      "oktaSwaLogin": true,
      "passwordLogin": true,
      "samlLogin": "OKTA",
      "vendorSsoLogin": "GOOGLE_WORKSPACE"
    },
    "mfaMethods": [
      "APP_TOTP",
      "PUSH_NOTIFICATION",
      "EMAIL_OTP",
      "U2F",
      "HARDWARE_TOTP",
      "PHONE_CALL",
      "SMS_OTP",
      "APP_PASSWORD",
      "GRID_CARD",
      "EXTERNAL_PROVIDER",
      "BACKUP_CODES",
      "WEBAUTHN"
    ],
    "mfaRegistered": true,
    "passwordId": "4c13674f-e88a-4411-bfa2-53a70468a898"
  },
  "object": "ACCOUNT",
  "old": null,
  "timestamp": 1698604061.0,
  "type": "CREATE",
  "version": "1"
}

Push Security Open Security Finding

#
Severity
informational
Log types
PushSecurity.Entities
Source
github.com/panther-labs/panther-analysis

Detection logic

def rule(event):
    if event.get("object") != "FINDING":
        return False

    event_type = event.get("type")

    if event_type == "CREATE":
        return True

    if event_type == "UPDATE" and event.deep_get("new", "state") == "OPEN":
        return True

    return False


def title(event):
    new_type = event.deep_get("new", "type")
    app_type = event.deep_get("new", "appType")
    return f"Open finding {new_type} for app {app_type}"

Rule specification

AnalysisType: rule
Filename: push_security_open_security_finding.py
RuleID: "Push.Security.Open.Security.Finding"
DisplayName: "Push Security Open Security Finding"
Enabled: true
LogTypes:
  - PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Entities events when all of the conditions below hold.

Condition

  • object is FINDING
  • any of:
    • type is CREATE
    • all of:
      • type is UPDATE
      • new.state is OPEN

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
typenew.type
appTypenew.appType

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "c478966c-f927-411c-b919-179832d3d50c",
  "new": {
    "accountId": null,
    "appId": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
    "appType": "PUSH_SECURITY",
    "creationTimestamp": 1698064423.0,
    "employeeId": "379ac7ea-ff2a-42ef-af37-06d2020dc46a",
    "id": "d6a32ba5-0532-4a66-8137-48cdf409c972",
    "passwordId": "c4a045a1-5331-4714-af83-6a361e98960d",
    "state": "OPEN",
    "type": "WEAK_PASSWORD"
  },
  "object": "FINDING",
  "old": null,
  "timestamp": 1698604061.0,
  "type": "CREATE",
  "version": "1"
}

Push Security Phishable MFA Method

#
Severity
informational
Log types
PushSecurity.Entities
Source
github.com/panther-labs/panther-analysis

Detection logic

identity_providers = ("MICROSOFT_365", "GOOGLE_WORKSPACE", "OKTA", "JUMPCLOUD", "PING")

phishable_mfa = ("EMAIL_OTP", "PHONE_CALL", "SMS", "APP_PASSWORD")


def rule(event):
    if event.get("object") != "ACCOUNT":
        return False

    mfa_methods = event.deep_get("new", "mfaMethods")

    for method in mfa_methods:
        if method in phishable_mfa:
            return True

    return False


def severity(event):
    if event.deep_get("new", "appType") in identity_providers:
        return "HIGH"
    return "INFO"


def title(event):
    mfa_methods = ", ".join(event.deep_get("new", "mfaMethods", default="No MFA"))
    new_email = event.deep_get("new", "email")
    app_type = event.deep_get("new", "appType", default=[])

    return f"{new_email} using phishable MFA method with {app_type}. \
            MFA methods enabled: {mfa_methods}"

Rule specification

AnalysisType: rule
Filename: push_security_phishable_mfa_method.py
RuleID: "Push.Security.Phishable.MFA.Method"
DisplayName: "Push Security Phishable MFA Method"
Enabled: true
LogTypes:
  - PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Entities events when all of the conditions below hold.

Condition

  • object is ACCOUNT
  • any element of new.mfaMethods matches:
    • new.mfaMethods is one of EMAIL_OTP, PHONE_CALL, SMS, APP_PASSWORD

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emailnew.email
appTypenew.appType

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "d1e5794f-666d-4cba-abae-c6d889ca1903",
  "new": {
    "appId": "67ef5c13-b5e6-4945-af7b-c11ac98f630f",
    "appType": "DROPBOX",
    "creationTimestamp": 1707775048.0,
    "email": "jet.black@issp.com",
    "employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
    "id": "5e15ce4c-6b93-4fbf-aed9-1890775efa90",
    "lastUsedTimestamp": null,
    "loginMethods": {
      "oidcLogin": null,
      "oktaSwaLogin": false,
      "passwordLogin": false,
      "samlLogin": null
    },
    "mfaMethods": [
      "SMS",
      "EMAIL_OTP"
    ],
    "mfaRegistered": false,
    "passwordId": null
  },
  "object": "ACCOUNT",
  "old": null
}

Push Security Phishing Attack

#
Severity
high
Log types
PushSecurity.Controls
Source
github.com/panther-labs/panther-analysis

Detection logic

def rule(event):
    if event.get("object") == "PASSWORD_PHISHING":
        return True

    return False


def severity(event):
    if event.deep_get("new", "mode") != "BLOCK":
        return "HIGH"
    return "LOW"


def title(event):
    app_type = event.deep_get("new", "appType")
    employee_email = event.deep_get("new", "employee", "email")
    new_mode = event.deep_get("new", "mode")
    return f"Phishing attack on app {app_type} user {employee_email}. \
             Attack detected in mode {new_mode}."

Rule specification

AnalysisType: rule
Filename: push_security_phishing_attack.py
RuleID: "Push.Security.Phishing.Attack"
DisplayName: "Push Security Phishing Attack"
Enabled: true
LogTypes:
  - PushSecurity.Controls
Severity: High
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Controls events when the condition below holds.

Condition

  • object is PASSWORD_PHISHING

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
objecteq
  • PASSWORD_PHISHING
field:"group.name" kind:eq value:"PASSWORD_PHISHING"

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
appTypenew.appType
emailnew.employee.email
modenew.mode

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "c478966c-f927-411c-b919-179832d3d50c",
  "new": {
    "appType": "OKTA",
    "browser": "CHROME",
    "employee": {
      "chatopsEnabled": true,
      "creationTimestamp": 1698669223.0,
      "department": "Security Engineering",
      "email": "john.hill@example.com",
      "firstName": "John",
      "id": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
      "lastName": "Hill",
      "licensed": true,
      "location": "New York"
    },
    "mode": "BLOCK",
    "os": "WINDOWS",
    "referrerUrl": "https://statics.teams.cdn.office.net/",
    "sourceIpAddress": "8.158.25.38",
    "url": "https://evil.com/okta.php",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
  },
  "object": "PASSWORD_PHISHING",
  "timestamp": 1698604061.0,
  "version": "1"
}

Push Security SaaS App MFA Method Changed

#
Severity
informational
Log types
PushSecurity.Entities
Source
github.com/panther-labs/panther-analysis

MFA method on SaaS app changed

Detection logic

def rule(event):
    if event.get("object") != "ACCOUNT":
        return False

    if event.get("old") is None:
        return False

    new_mfa_methods = set(event.deep_get("new", "mfaMethods"))
    old_mfa_methods = set(event.deep_get("old", "mfaMethods", default=[]))

    if new_mfa_methods != old_mfa_methods:
        return True

    return False


def severity(event):
    if event.deep_get("new", "mfaMethods") == []:
        return "HIGH"
    return "LOW"


def title(event):
    mfa_methods = ", ".join(event.deep_get("new", "mfaMethods", default="No MFA"))
    new_email = event.deep_get("new", "email")
    new_apptype = event.deep_get("new", "appType")

    if mfa_methods == "":
        return f"{new_email} removed all MFA methods on {new_apptype}"
    return f"{new_email} changed MFA method to {mfa_methods} on {new_apptype}"

Rule specification

AnalysisType: rule
Filename: push_security_mfa_method_changed.py
RuleID: "Push.Security.MFA.Method.Changed"
DisplayName: "Push Security SaaS App MFA Method Changed"
Enabled: true
LogTypes:
  - PushSecurity.Entities
Severity: Info
Description: MFA method on SaaS app changed
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Entities events when all of the conditions below hold.

Condition

  • object is ACCOUNT
  • old is present

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
objecteq
  • ACCOUNT
field:"group.name" kind:eq value:"ACCOUNT"
oldis_not_null
  • (no value, null check)
field:"old" kind:is_not_null

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emailnew.email
appTypenew.appType

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "d1e5794f-666d-4cba-abae-c6d889ca1903",
  "new": {
    "appId": "67ef5c13-b5e6-4945-af7b-c11ac98f630f",
    "appType": "CONTENTFUL",
    "creationTimestamp": 1707775048.0,
    "email": "jet.black@issp.com",
    "employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
    "id": "5e15ce4c-6b93-4fbf-aed9-1890775efa90",
    "lastUsedTimestamp": null,
    "loginMethods": {
      "oidcLogin": null,
      "oktaSwaLogin": false,
      "passwordLogin": false,
      "samlLogin": null
    },
    "mfaMethods": [],
    "mfaRegistered": false,
    "passwordId": null
  },
  "object": "ACCOUNT",
  "old": {
    "appId": "67ef5c13-b5e6-4945-af7b-c11ac98f630f",
    "appType": "CONTENTFUL",
    "creationTimestamp": 1707775048.0,
    "email": "jet.black@issp.com",
    "employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
    "id": "5e15ce4c-6b93-4fbf-aed9-1890775efa90",
    "lastUsedTimestamp": null,
    "loginMethods": {
      "oidcLogin": null,
      "oktaSwaLogin": false,
      "passwordLogin": false,
      "samlLogin": null
    },
    "mfaMethods": [
      "SMS"
    ],
    "mfaRegistered": false,
    "passwordId": null
  },
  "timestamp": 1707775049.0,
  "type": "CREATE",
  "version": "1"
}

Push Security Unauthorized IdP Login

#
Severity
high
Log types
PushSecurity.Activity
Tags
Configuration Required
Reference
github.com
Source
github.com/panther-labs/panther-analysis

Login to application with unauthorized identity provider which could indicate a SAMLjacking attack.

Detection logic

# Configure allowed identity provider logins to SaaS apps
allowed_idps = {
    "GOOGLE_WORKSPACE": {"OIDC_LOGIN", "SAML_LOGIN"},
    "OKTA": {"PASSWORD_LOGIN"},
    None: {"PASSWORD_LOGIN"},
}


def rule(event):
    if event.get("object") != "LOGIN":
        return False

    identity_provider = event.deep_get("new", "identityProvider")
    login_type = event.deep_get("new", "loginType")

    if identity_provider in allowed_idps and login_type in allowed_idps[identity_provider]:
        return False

    return True


def title(event):
    identity_provider = event.deep_get("new", "identityProvider", default="Null identityProvider")
    login_type = event.deep_get("new", "loginType", default="Null loginType")
    app_type = event.deep_get("new", "appType", default="Null appType")
    new_email = event.deep_get("new", "email")

    return f"Unauthorized identity provider in use. User: {new_email} \
        used {identity_provider} {login_type} on {app_type}"

Rule specification

AnalysisType: rule
Filename: push_security_unauthorized_idp_login.py
RuleID: "Push.Security.Unauthorized.IdP.Login"
DisplayName: "Push Security Unauthorized IdP Login"
Enabled: false
Tags:
  - Configuration Required
LogTypes:
  - PushSecurity.Activity
Severity: High
Description: Login to application with unauthorized identity provider which could indicate a SAMLjacking attack.
Reference: https://github.com/pushsecurity/saas-attacks/blob/main/techniques/samljacking/description.md
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on PushSecurity.Activity events when the condition below holds.

Condition

  • object is LOGIN

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emailnew.email
identityProvidernew.identityProvider
loginTypenew.loginType
appTypenew.appType

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "id": "d240e3f2-3cd6-425f-a835-dad0ff237d09",
  "new": {
    "accountId": "a93b45a7-fdce-489e-b76d-2bd6862a62ba",
    "appId": "8348ca36-d254-4e1b-8f31-6837d82fc5cb",
    "appType": "GOOGLE_WORKSPACE",
    "browser": "EDGE",
    "email": "jet.black@issp.com",
    "employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
    "identityProvider": "GOOGLE_WORKSPACE",
    "leakedPassword": false,
    "loginTimestamp": 1707773386.0,
    "loginType": "PASSWORD_LOGIN",
    "os": "WINDOWS",
    "passwordId": "6ae9f0b2-9300-43f0-b210-c0d3c16640f8",
    "passwordManuallyTyped": false,
    "sourceIpAddress": "35.90.103.134",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.2420.81",
    "weakPassword": false,
    "weakPasswordReasons": null
  },
  "object": "LOGIN",
  "timestamp": 1707774319.0,
  "version": "1"
}