Skip to content

Account Security Monitor

The Account Security Monitor gives every user visibility into their own authentication activity and active sessions. Administrators gain additional controls to view security events across all users in the organization, manage sessions, and configure org-wide security policy.

Every authentication event against your Arbitex account is recorded with full context: timestamp, event type, IP address, device information, and GeoIP-enriched location data. The Account Security Monitor surfaces this history through the Cloud Portal and through the security events API.


Authentication events flow through a multi-stage pipeline before appearing in the security history:

User action (login / MFA / logout)
Auth service (auth.py)
Session management (sessions.py)
- create_session: DB write + session_store cache
- enforce_session_limit: FIFO eviction if > max concurrent
log_event service (services/audit.py)
- Writes AuditLog row to audit_log table
- GeoIP enrichment applied (src_ip → country/city/ISP)
- CredInt enrichment applied (credential corpus match check)
Audit log (tenant-scoped, cursor-paginated)
- Visible via GET /v1/audit/events
- HMAC chain fields excluded from customer-facing API

When a user logs in:

  1. A session record is created with the token_jti from the issued JWT.
  2. The session is written to the database and cached in the session store.
  3. enforce_session_limit runs immediately. If the user has more active sessions than the org’s concurrent limit (default: 5), the oldest sessions are evicted in FIFO order.
  4. Each evicted session has its token_jti added to the JWT blacklist, immediately invalidating the associated token.
  5. An auth.session_evicted event is written to the audit log for each eviction.

Session records have a soft is_active flag — logout and force-revocation set is_active = false without deleting the row. The JWT blacklist ensures revoked tokens are rejected even before the JWT’s native expiry.

Every auth event is enriched at write time using the MaxMind GeoLite2 database:

  • SaaS deployments: enrichment runs in-process using the hosted GeoLite2 database.
  • Hybrid Outpost: enrichment runs at the Outpost using the bundled MMDB.
  • Air-gap deployments: uses the bundled MMDB at /etc/arbitex/geoip/GeoLite2-City.mmdb. Update this file manually during routine air-gap media refreshes.

Private (RFC 1918), CGNAT, and loopback addresses resolve to empty location fields.


The following 12 event types are recorded in the security history. These are the action values returned by the API and displayed in the Cloud Portal event timeline.

Event Type Description
auth.login_success Successful interactive login (password or passkey)
auth.login_failed Failed login attempt — wrong password, locked account, or unrecognized user
auth.logout Explicit logout initiated by user
auth.mfa_enabled TOTP or WebAuthn MFA factor enabled on account
auth.mfa_disabled MFA factor disabled by user or admin
auth.mfa_verify_success MFA challenge completed successfully during login
auth.mfa_verify_failed MFA challenge failed (wrong code or expired token)
auth.webauthn_registered New WebAuthn passkey registered on the account
auth.webauthn_login Successful login using a WebAuthn passkey
auth.webauthn_revoked WebAuthn passkey removed from account
auth.session_force_logout Session terminated by an admin force-logout action
auth.session_evicted Session terminated automatically due to concurrent session limit

All events include the user_id of the authenticating user and the source_ip of the origin request.


Navigate to Account → Security or go directly to /portal/my-security.

The security history page shows:

  • Event timeline — the last 90 days of auth events, most recent first, with relative timestamps (absolute on hover)
  • Active Sessions panel — all currently valid sessions with device and location details
  • Filters — event type, date range
  • Auto-refresh — the timeline refreshes automatically every 60 seconds

Each event row shows:

Column Description
Icon Color-coded event type indicator (green = success, red = failure, amber = warning)
Event label Human-readable event type
Relative time Time since event (e.g., “5m ago”); hover for absolute timestamp
IP address Source IP at time of event
Location City and country inferred from IP via GeoIP
Device Browser, app, and OS parsed from User-Agent string
Anon IP badges VPN / Proxy / Tor / Hosting flags when detected

Click any event row to expand full metadata including the raw User-Agent string and any extra event metadata.

Use the filter controls to narrow results:

  • Event type — one of the 12 event types, or “All events”
  • Date range — start date and end date pickers

Query your own auth events using the user_id=me parameter:

Terminal window
curl -H "Authorization: Bearer $TOKEN" \
"https://api.arbitex.ai/v1/audit/events?user_id=me&limit=50"
GET /v1/audit/events

Host: https://api.arbitex.ai

Parameter Type Description
user_id string Filter by user UUID. Use "me" to filter by the authenticated user. Non-admin users can only use "me".
action string Filter by exact action string (e.g., auth.login_success)
created_after ISO 8601 Lower bound on event timestamp (inclusive)
created_before ISO 8601 Upper bound on event timestamp (inclusive)
cursor string Opaque pagination cursor from a previous response’s next_cursor
limit integer Max events per page, 1–500 (default: 50)
{
"events": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"action": "auth.login_success",
"user_id": "a1b2c3d4-0000-0000-0000-000000000001",
"org_id": "a1b2c3d4-0000-0000-0000-000000000002",
"model_id": null,
"provider": null,
"source": "saas",
"outpost_id": null,
"created_at": "2026-03-14T10:00:00Z",
"src_country_code": "US",
"src_city": "San Francisco",
"src_isp": "Comcast Cable",
"credint_hit": false,
"credint_confidence": null,
"frequency_bucket": null,
"ocsf_class_uid": 3002,
"ocsf_class": "authentication"
}
],
"next_cursor": "eyJ0IjoiMjAyNi0wMy0xNFQwOTo1OTo1OVoiLCJpIjoiM2ZhODVmNjQifQ",
"has_more": true
}

The user_id=me alias resolves to the authenticated user’s own UUID at query time. It allows users to query their own events without knowing their UUID:

Terminal window
# Self-service: retrieve my own auth events
curl -H "Authorization: Bearer $TOKEN" \
"https://api.arbitex.ai/v1/audit/events?user_id=me&action=auth.login_failed&limit=10"

Non-admin users can only use user_id=me. Admin users can pass any user UUID to view another user’s events. Passing a non-UUID value other than "me" returns 400.


The Active Sessions panel at /portal/my-security lists all sessions currently active under your account.

Each session shows:

Field Description
Created When the session was established (login time)
Last active Most recent authenticated request
Expires Session expiry time
IP Address IP at session creation
Location GeoIP city and country
Device Browser and OS
Current Badge indicates the session you are currently using

Arbitex enforces a concurrent session limit per user. When a login creates a new session that would exceed the limit, the oldest sessions are evicted in FIFO order. Default limit: 5 concurrent sessions.

Admins can override this via the max_concurrent_sessions key in system configuration. Contact Arbitex support to adjust this limit for your organization.

GET /api/v1/admin/sessions

Host: https://api.arbitex.ai

Terminal window
# All org sessions (admin)
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/sessions"
# Filter to a specific user
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/sessions?user_id=a1b2c3d4-0000-0000-0000-000000000001"

Response schema:

{
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"user_id": "a1b2c3d4-0000-0000-0000-000000000001",
"token_jti": "d4f8e2c1-1234-5678-abcd-ef0123456789",
"created_at": "2026-03-14T08:00:00Z",
"last_activity": "2026-03-14T10:15:00Z",
"expires_at": "2026-03-21T08:00:00Z",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 ...",
"is_active": true
}
],
"total": 1
}

Cloud Portal:

  1. Find the session in the Active Sessions panel.
  2. Click Revoke on the row.
  3. Confirm the revocation dialog.

The session is invalidated immediately. Any in-flight requests using that session token will receive 401 Unauthorized. The event is logged as auth.session_force_logout.

You cannot revoke your current session from the UI; use Sign Out instead.

API (admin — single session):

Terminal window
DELETE /api/v1/admin/sessions/{session_id}
Terminal window
curl -X DELETE \
-H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6"

Returns the deactivated session object. An auth.session_force_logout audit event is written with metadata.admin_id, metadata.session_id, and metadata.reason: "admin_force_logout".

API (admin — all sessions for a user):

Terminal window
DELETE /api/v1/admin/users/{user_id}/sessions
Terminal window
curl -X DELETE \
-H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/users/a1b2c3d4-0000-0000-0000-000000000001/sessions"

Returns the list of revoked sessions. Returns 404 if the user has no active sessions.


  • User self-service: Navigate to Account → Security (/portal/my-security).
  • Admin org settings: Navigate to Admin → Security (/portal/admin/security).

From /portal/my-security, users can:

  • Enable TOTP — scan a QR code to add a time-based OTP authenticator.
  • Enable WebAuthn — register a passkey (hardware key or platform authenticator).
  • Disable an MFA factor — generates an auth.mfa_disabled audit event.
  • View registered passkeys — list WebAuthn credentials with registration date and last used.

Admins can require MFA for all users in the organisation via the Security settings page or the API.

Enforcement Level Behaviour
off MFA not enforced. Users may enable it optionally.
optional MFA encouraged but not gated. Requests proceed regardless of MFA status.
required All sensitive endpoint requests must carry a JWT with mfa_verified: true. Requests without this claim are rejected with 403.

Portal: Navigate to Admin → Security → MFA Policy, select the enforcement level, and click Save.

API:

Terminal window
# Get current policy
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/org/mfa-policy"
# Enable mandatory MFA
curl -X PUT \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"enforcement_level": "required"}' \
"https://api.arbitex.ai/api/v1/admin/org/mfa-policy"

The new enforcement level takes effect immediately after the API call succeeds (the in-memory policy cache is cleared synchronously). See API Reference — Batch 12 for full schema details.

Users who have forgotten their password can reset it via the Sign In page. The forgot-password flow is rate-limited to 3 requests per email per minute and uses constant-time responses to prevent user enumeration.

Admins can initiate a forced password reset for any user:

Terminal window
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/users/{user_id}/reset-password"

The returned reset token is single-use and expires in 15 minutes. Deliver it to the user via a trusted channel.


Each event and session record includes device information parsed from the HTTP User-Agent header at the time of authentication:

Field Description
user_agent Raw User-Agent string (visible in expanded event row)

Browser, OS, and device type are parsed from the User-Agent for display in the portal. Arbitex does not install tracking software or use browser fingerprinting beyond the standard User-Agent string.

Every authentication event is enriched with geographic location data using the MaxMind GeoLite2 database:

Field Description
src_country_code ISO 3166-1 alpha-2 country code
src_city City name (best-effort; may be absent for some IPs)
src_isp Internet service provider for the source IP

Accuracy notes:

  • City-level accuracy is approximately 80% for covered IPs.
  • Private, RFC 1918, and CGNAT addresses resolve to empty location fields.
  • GeoIP data is best-effort and should not be used as a sole indicator for access control decisions.

Administrators with the admin role can view and manage security events for any user in the organization.

Navigate to Admin → Users → [User] → Security Events.

The admin view provides the same event timeline and filter controls as the user self-service view, plus:

  • All event types across all 12 categories
  • Export — download events as CSV for audit evidence
  • Force Logout — terminate all active sessions for the selected user
Terminal window
# List auth events for a specific user
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/v1/audit/events?user_id=a1b2c3d4-0000-0000-0000-000000000001&limit=50"
# Force-logout a single session
curl -X DELETE \
-H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/sessions/3fa85f64-5717-4562-b3fc-2c963f66afa6"
# Force-logout all sessions for a user
curl -X DELETE \
-H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.arbitex.ai/api/v1/admin/users/a1b2c3d4-0000-0000-0000-000000000001/sessions"

All force-logout actions are logged as auth.session_force_logout with the admin’s identity as the actor and the target session ID in the event metadata.

The admin sessions view (/portal/admin/sessions) shows all active sessions across the organization.

Admins can:

  • Search by user email or IP address
  • Filter by session age or location country
  • Revoke individual sessionsDELETE /api/v1/admin/sessions/{session_id}
  • Revoke all sessions for a userDELETE /api/v1/admin/users/{user_id}/sessions

The Account Security Monitor does not send automated alerts by default. To configure alerts on suspicious auth events (e.g., auth.login_failed spikes, logins from new countries), route audit events to your SIEM and define alert rules there.

See SIEM Integration Guide for connector configuration.


Auth event records follow the standard audit log retention policy:

  • Hot (searchable): 90 days
  • Archive: 2 years (compliance export)

Events older than 90 days are available via the compliance export API. See Compliance Audit Evidence Guide.