litesoc / litesoc-php
Official PHP SDK for LiteSOC - Security event tracking and threat detection
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.9
Requires (Dev)
- orchestra/testbench: ^9.0
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
README
Official PHP SDK for LiteSOC - Security event tracking and threat detection for your applications.
Installation
composer require litesoc/litesoc-php
Quick Start
use LiteSOC\LiteSOC; // Initialize the SDK $litesoc = new LiteSOC('your-api-key'); // Track a login failure - LiteSOC auto-enriches with GeoIP & Network Intelligence $litesoc->track('auth.login_failed', [ 'actor_id' => 'user_123', 'actor_email' => 'user@example.com', 'user_ip' => '192.168.1.1', // Required for Security Intelligence 'metadata' => ['reason' => 'invalid_password'] ]); // Flush remaining events before shutdown $litesoc->flush();
Features
- ✅ 26 standard security event types - Authentication, authorization, admin, data, and security events
- ✅ Management API - Query alerts and events programmatically (Business/Enterprise plans)
- ✅ Custom exceptions - Specific exceptions for auth, rate limits, and plan restrictions
- ✅ Automatic batching - Events are batched for efficient delivery
- ✅ Batch ingestion helper -
trackBatch()sends up to 100 events in a single request - ✅ Retry logic - Failed events are automatically retried
- ✅ Laravel integration - Service provider, facade, and config publishing
- ✅ PHP 8.2+ - Modern PHP with full type declarations
- 🗺️ GeoIP Enrichment - Automatic location data from IP addresses
- 🛡️ Network Intelligence - VPN, Tor, Proxy & Datacenter detection
- 📊 Threat Scoring - Auto-assigned severity (Low → Critical)
Security Intelligence (Automatic Enrichment)
When you provide user_ip, LiteSOC automatically enriches your events with:
🗺️ Geolocation
- Country & City resolution
- Latitude/Longitude coordinates
- Interactive map visualization in dashboard
🛡️ Network Intelligence
- VPN Detection - NordVPN, ExpressVPN, Surfshark, etc.
- Tor Exit Nodes - Anonymizing network detection
- Proxy Detection - HTTP/SOCKS proxy identification
- Datacenter IPs - AWS, GCP, Azure, DigitalOcean, etc.
📊 Threat Scoring
Events are auto-classified by severity:
- Low - Normal activity
- Medium - Unusual patterns
- High - Suspicious behavior
- Critical - Active threats (triggers instant alerts)
Important: Always include
user_ipfor full Security Intelligence features.
Configuration Options
use LiteSOC\LiteSOC; $litesoc = new LiteSOC('your-api-key', [ 'endpoint' => 'https://...', // Custom API endpoint 'batching' => true, // Enable event batching (default: true) 'batch_size' => 10, // Events before auto-flush (default: 10) 'flush_interval' => 5.0, // Seconds between auto-flushes (default: 5.0) 'debug' => false, // Enable debug logging (default: false) 'silent' => true, // Fail silently on errors (default: true) 'timeout' => 5.0, // Request timeout in seconds (default: 5.0) ]);
Tracking Events
Basic Usage
// Track any event type $litesoc->track('auth.login_failed', [ 'actor_id' => 'user_123', 'actor_email' => 'user@example.com', 'user_ip' => '192.168.1.1' ]);
Batch Ingestion with trackBatch (v2.5.0+)
To reduce HTTP overhead and align with the backend batch ingestion contract, you can send up to 100 events in a single call:
use LiteSOC\LiteSOC; $litesoc = new LiteSOC('your-api-key'); $accepted = $litesoc->trackBatch([ [ 'event_name' => 'auth.login_success', 'actor_id' => 'user_123', 'actor_email' => 'user@example.com', 'user_ip' => '203.0.113.50', 'metadata' => ['method' => 'password'], ], [ 'event_name' => 'data.export', 'actor_id' => 'user_123', 'user_ip' => '203.0.113.50', 'metadata' => ['table' => 'orders', 'rows' => 500], ], ]); echo "{$accepted} events accepted";
Using Event Type Constants
use LiteSOC\EventType; $litesoc->track(EventType::AUTH_LOGIN_FAILED, [ 'actor_id' => 'user_123', 'user_ip' => '192.168.1.1' ]);
Using SecurityEvents Class
use LiteSOC\SecurityEvents; // Use predefined security event types $litesoc->track(SecurityEvents::AUTH_LOGIN_FAILED, [ 'actor_id' => 'user_123', 'user_ip' => '192.168.1.1' ]); // Get all 26 standard events $allEvents = SecurityEvents::all(); // Validate an event type if (SecurityEvents::isValid('auth.login_failed')) { // Valid standard event }
With Severity Level
use LiteSOC\EventSeverity; $litesoc->track('security.suspicious_activity', [ 'actor_id' => 'user_123', 'user_ip' => '192.168.1.1', 'severity' => EventSeverity::CRITICAL, 'metadata' => ['reason' => 'impossible travel detected'] ]);
With Metadata
$litesoc->track('data.export', [ 'actor_id' => 'user_123', 'user_ip' => '192.168.1.1', 'metadata' => [ 'file_type' => 'csv', 'record_count' => 1000, 'export_reason' => 'monthly_report' ] ]);
Convenience Methods
The SDK provides convenience methods for common security events:
// Track login failures $litesoc->trackLoginFailed('user_123', ['user_ip' => '192.168.1.1']); // Track login successes $litesoc->trackLoginSuccess('user_123', ['user_ip' => '192.168.1.1']); // Track privilege escalation (critical severity) $litesoc->trackPrivilegeEscalation('admin_user', ['user_ip' => '192.168.1.1']); // Track sensitive data access (high severity) $litesoc->trackSensitiveAccess('user_123', 'customer_pii_table', ['user_ip' => '192.168.1.1']); // Track bulk deletions (high severity) $litesoc->trackBulkDelete('admin_user', 500, ['user_ip' => '192.168.1.1']); // Track role changes $litesoc->trackRoleChanged('user_123', 'viewer', 'admin', ['user_ip' => '192.168.1.1']); // Track access denied $litesoc->trackAccessDenied('user_123', '/admin/settings', ['user_ip' => '192.168.1.1']);
Laravel Integration
Installation
composer require litesoc/litesoc-php
The package auto-discovers the service provider and facade.
Configuration
Publish the config file:
php artisan vendor:publish --tag=litesoc-config
Add your API key to .env:
LITESOC_API_KEY=your-api-key
Usage with Facade
use LiteSOC\Laravel\Facades\LiteSOC; // Track events using the facade LiteSOC::track('auth.login_failed', [ 'actor_id' => auth()->id(), 'user_ip' => request()->ip() ]); // Use convenience methods LiteSOC::trackLoginSuccess(auth()->id(), [ 'actor_email' => auth()->user()->email, 'user_ip' => request()->ip() ]);
Usage with Dependency Injection
use LiteSOC\LiteSOC; class LoginController extends Controller { public function __construct( private LiteSOC $litesoc ) {} public function login(Request $request) { // Attempt authentication if (Auth::attempt($request->only('email', 'password'))) { $this->litesoc->trackLoginSuccess(auth()->id(), [ 'actor_email' => auth()->user()->email, 'user_ip' => $request->ip() ]); return redirect('/dashboard'); } $this->litesoc->trackLoginFailed($request->email, [ 'user_ip' => $request->ip() ]); return back()->withErrors(['email' => 'Invalid credentials']); } }
Event Listener Integration
// app/Providers/EventServiceProvider.php protected $listen = [ \Illuminate\Auth\Events\Login::class => [ \App\Listeners\TrackLoginSuccess::class, ], \Illuminate\Auth\Events\Failed::class => [ \App\Listeners\TrackLoginFailed::class, ], ]; // app/Listeners/TrackLoginSuccess.php use LiteSOC\Laravel\Facades\LiteSOC; use Illuminate\Auth\Events\Login; class TrackLoginSuccess { public function handle(Login $event): void { LiteSOC::trackLoginSuccess($event->user->id, [ 'actor_email' => $event->user->email, 'user_ip' => request()->ip() ]); } } // app/Listeners/TrackLoginFailed.php use LiteSOC\Laravel\Facades\LiteSOC; use Illuminate\Auth\Events\Failed; class TrackLoginFailed { public function handle(Failed $event): void { LiteSOC::trackLoginFailed($event->credentials['email'] ?? 'unknown', [ 'user_ip' => request()->ip() ]); } }
Middleware for Auth Events
// app/Http/Middleware/TrackSecurityEvents.php namespace App\Http\Middleware; use Closure; use LiteSOC\Laravel\Facades\LiteSOC; class TrackSecurityEvents { public function handle($request, Closure $next) { return $next($request); } public function terminate($request, $response) { // Track access denied (403 responses) if ($response->status() === 403) { LiteSOC::trackAccessDenied( auth()->id() ?? 'anonymous', $request->path(), ['user_ip' => $request->ip()] ); } } }
Event Types
26 Standard Events (Primary)
These are the primary events for comprehensive security coverage:
| Category | Event Type | Description |
|---|---|---|
| Auth | auth.login_success |
Successful user login |
| Auth | auth.login_failed |
Failed login attempt |
| Auth | auth.logout |
User logout |
| Auth | auth.password_reset |
Password reset completed |
| Auth | auth.mfa_enabled |
MFA enabled on account |
| Auth | auth.mfa_disabled |
MFA disabled on account |
| Auth | auth.session_expired |
Session timeout/expiry |
| Auth | auth.token_refreshed |
Token refresh |
| Authz | authz.role_changed |
User role modified |
| Authz | authz.permission_granted |
Permission assigned |
| Authz | authz.permission_revoked |
Permission removed |
| Authz | authz.access_denied |
Access denied event |
| Admin | admin.privilege_escalation |
Admin privilege escalation |
| Admin | admin.user_impersonation |
Admin impersonating user |
| Admin | admin.settings_changed |
System settings modified |
| Admin | admin.api_key_created |
New API key generated |
| Admin | admin.api_key_revoked |
API key revoked |
| Admin | admin.user_suspended |
User account suspended |
| Admin | admin.user_deleted |
User account deleted |
| Data | data.bulk_delete |
Bulk data deletion |
| Data | data.sensitive_access |
PII/sensitive data accessed |
| Data | data.export |
Data export operation |
| Security | security.suspicious_activity |
Suspicious behavior detected |
| Security | security.rate_limit_exceeded |
Rate limit triggered |
| Security | security.ip_blocked |
IP address blocked |
| Security | security.brute_force_detected |
Brute force attack detected |
Extended Events (Backward Compatible)
Additional events for granular tracking:
auth.password_changed,auth.password_reset_requested,auth.mfa_challenge_success,auth.mfa_challenge_failed,auth.session_createduser.created,user.updated,user.deleted,user.email_changed,user.profile_updatedauthz.role_assigned,authz.role_removed,authz.access_grantedadmin.invite_sent,admin.invite_accepted,admin.member_removeddata.import,data.bulk_update,data.download,data.upload,data.sharedsecurity.ip_unblocked,security.account_locked,security.impossible_travel,security.geo_anomalyapi.key_used,api.rate_limited,api.error,api.webhook_sent,api.webhook_failedbilling.subscription_created,billing.subscription_cancelled,billing.payment_succeeded,billing.payment_failed
Queue Management
// Get current queue size $queueSize = $litesoc->getQueueSize(); // Manually flush all events $litesoc->flush(); // Clear queue without sending $litesoc->clearQueue(); // Graceful shutdown $litesoc->shutdown();
Management API (Business/Enterprise)
The Management API allows you to query alerts and events programmatically. Requires a Business or Enterprise plan.
API Endpoints: These methods interact with
/api/v1/alertsand/api/v1/events
Get Alerts
use LiteSOC\LiteSOC; $litesoc = new LiteSOC('your-api-key'); // Get all alerts $result = $litesoc->getAlerts(); // Returns: // [ // 'success' => true, // 'data' => [ // ['id' => 'alert_123', 'alert_type' => 'impossible_travel', 'severity' => 'critical', ...], // ['id' => 'alert_456', 'alert_type' => 'brute_force', 'severity' => 'warning', ...], // ], // 'pagination' => ['total' => 42, 'limit' => 20, 'offset' => 0, 'has_more' => true], // 'meta' => ['plan' => 'business', 'retention_days' => 90] // ] // Get alerts with filters $result = $litesoc->getAlerts([ 'severity' => 'critical', // 'critical', 'warning', 'info' 'status' => 'active', // 'active', 'resolved', 'safe' 'alert_type' => 'impossible_travel', 'limit' => 10, 'offset' => 0, ]); // Access alerts from the response foreach ($result['data'] as $alert) { echo $alert['id'] . ': ' . $alert['title']; }
Get Single Alert
$result = $litesoc->getAlert('alert_abc123'); // Returns: // [ // 'success' => true, // 'data' => [ // 'id' => 'alert_abc123', // 'alert_type' => 'impossible_travel', // 'severity' => 'critical', // 'status' => 'active', // 'title' => 'Impossible Travel Detected', // 'description' => 'Login from New York, then Tokyo within 30 minutes', // 'actor_id' => 'user_123', // 'trigger_event_id' => 'evt_xyz789', // 'created_at' => '2026-03-02T10:30:00Z', // 'forensics' => [...], // Network intelligence & geolocation (Pro/Enterprise) // ], // 'meta' => ['plan' => 'business', 'retention_days' => 90] // ] $alert = $result['data']; echo $alert['title'] . ' - ' . $alert['severity'];
Resolve Alert
// Mark an alert as resolved with resolution type and notes $result = $litesoc->resolveAlert( 'alert_abc123', 'blocked_ip', // Resolution type: 'blocked_ip', 'false_positive', 'investigated', etc. 'Blocked IP in firewall' // Internal notes (optional) ); // Returns: // [ // 'success' => true, // 'data' => ['id' => 'alert_abc123', 'status' => 'resolved', 'resolved_at' => '...'], // ] // Mark an alert as safe (false positive) $result = $litesoc->markAlertSafe( 'alert_abc123', 'Expected behavior from automated testing' // Internal notes (optional) ); // Returns: // [ // 'success' => true, // 'data' => ['id' => 'alert_abc123', 'status' => 'safe'], // ]
Get Events
// Get recent events (default limit: 20) $result = $litesoc->getEvents(); // Returns: // [ // 'success' => true, // 'data' => [...events], // 'pagination' => ['total' => 100, 'limit' => 20, 'offset' => 0, 'has_more' => true], // 'meta' => ['plan' => 'business', 'retention_days' => 90, 'redacted' => false] // ] // Get events with filters $result = $litesoc->getEvents(50, [ 'event_name' => 'auth.login_failed', // Filter by event type 'actor_id' => 'user_123', // Filter by actor 'severity' => 'critical', // 'critical', 'warning', or 'info' 'offset' => 10, // Pagination offset ]); // Access events from the response foreach ($result['data'] as $event) { echo $event['event_name'] . ': ' . $event['actor']['id']; }
Get Single Event
$result = $litesoc->getEvent('event_xyz789'); // Returns: // [ // 'success' => true, // 'data' => [...event data], // 'meta' => ['plan' => 'business', 'retention_days' => 90, 'redacted' => false] // ] $event = $result['data']; echo $event['event_name'];
Plan Awareness & Quota Headers
The SDK automatically captures plan and quota information from API response headers:
Response Metadata
After any Management API call, you can access plan information:
use LiteSOC\LiteSOC; $litesoc = new LiteSOC('your-api-key'); // Make an API call first $alerts = $litesoc->getAlerts(); // Get plan metadata from response headers $planInfo = $litesoc->getPlanInfo(); if ($planInfo) { echo "Plan: " . $planInfo->plan; // e.g., "business", "enterprise" echo "Retention: " . $planInfo->retentionDays . " days"; echo "Cutoff: " . $planInfo->cutoffDate; // ISO 8601 timestamp } // Check if plan info is available if ($litesoc->hasPlanInfo()) { // Plan data has been populated }
Headers Parsed
| Header | Property | Description |
|---|---|---|
X-LiteSOC-Plan |
plan |
Current plan name (starter, business, enterprise) |
X-LiteSOC-Retention |
retentionDays |
Data retention period in days |
X-LiteSOC-Cutoff |
cutoffDate |
Earliest accessible data timestamp |
ResponseMetadata Class
use LiteSOC\ResponseMetadata; // Access properties directly (readonly) $planInfo = $litesoc->getPlanInfo(); $plan = $planInfo->plan; // string|null $days = $planInfo->retentionDays; // int|null $cutoff = $planInfo->cutoffDate; // string|null // Helper methods $planInfo->hasPlanInfo(); // bool $planInfo->hasRetentionInfo(); // bool $planInfo->toArray(); // array
Plan-Restricted Features (403 Handling)
When accessing features that require a higher plan, the SDK throws PlanRestrictedException:
use LiteSOC\Exceptions\PlanRestrictedException; try { $alerts = $litesoc->getAlerts(); } catch (PlanRestrictedException $e) { echo "Upgrade required: " . $e->getMessage(); echo "Upgrade at: " . $e->getUpgradeUrl(); // https://www.litesoc.io/pricing echo "Required plan: " . $e->getRequiredPlan(); }
Exception Handling
The SDK provides specific exceptions for different error scenarios:
use LiteSOC\LiteSOC; use LiteSOC\Exceptions\LiteSOCException; use LiteSOC\Exceptions\AuthenticationException; use LiteSOC\Exceptions\RateLimitException; use LiteSOC\Exceptions\PlanRestrictedException; $litesoc = new LiteSOC('your-api-key', ['silent' => false]); try { $alerts = $litesoc->getAlerts(); } catch (AuthenticationException $e) { // Invalid or missing API key (401) error_log('Auth failed: ' . $e->getMessage()); } catch (PlanRestrictedException $e) { // Feature requires higher plan (403) error_log('Upgrade required: ' . $e->getRequiredPlan()); } catch (RateLimitException $e) { // Rate limit exceeded (429) error_log('Rate limited. Retry after: ' . $e->getRetryAfter() . ' seconds'); } catch (LiteSOCException $e) { // Other API errors error_log('API error: ' . $e->getMessage() . ' (Status: ' . $e->getStatusCode() . ')'); }
Exception Hierarchy
LiteSOCException (base)
├── AuthenticationException (401)
├── PlanRestrictedException (403)
└── RateLimitException (429)
Error Handling (Silent Mode)
By default, the SDK fails silently (silent => true). To catch errors:
$litesoc = new LiteSOC('your-api-key', ['silent' => false]); try { $litesoc->track('auth.login_failed', ['actor_id' => 'user_123']); $litesoc->flush(); } catch (\Exception $e) { // Handle error error_log("Failed to track event: " . $e->getMessage()); }
Debug Mode
Enable debug logging to troubleshoot issues:
$litesoc = new LiteSOC('your-api-key', ['debug' => true]); // Logs will be printed to stdout
For Laravel, set in your .env:
LITESOC_DEBUG=true
Non-Blocking / Async Usage
By default, the SDK is synchronous - HTTP requests block until complete. However, the SDK has safeguards:
- Silent mode (
silent => truedefault): Errors are logged, not thrown - Timeout (
timeout => 30.0default): Prevents indefinite blocking - Batching: Reduces number of HTTP calls
True Non-Blocking with fastcgi_finish_request()
For PHP-FPM environments (Laravel, Symfony, etc.), you can achieve true non-blocking behavior by sending the response to the client before flushing events:
// In a controller or middleware public function login(Request $request) { // ... authentication logic ... // Queue the security event (fast, no HTTP call yet) $litesoc->track('auth.login_success', [ 'actor_id' => auth()->id(), 'user_ip' => $request->ip() ]); // Return response to client immediately $response = redirect('/dashboard'); // Finish the request - client receives response NOW if (function_exists('fastcgi_finish_request')) { // Send response headers and body to client $response->send(); // Close the connection - client is done waiting fastcgi_finish_request(); // This runs AFTER the client has received their response $litesoc->flush(); } return $response; }
Laravel Middleware for Non-Blocking Flush
Create a middleware that flushes events after the response is sent:
// app/Http/Middleware/FlushLiteSOCEvents.php namespace App\Http\Middleware; use Closure; use LiteSOC\LiteSOC; class FlushLiteSOCEvents { public function __construct(private LiteSOC $litesoc) {} public function handle($request, Closure $next) { return $next($request); } /** * Flush events after response is sent to client */ public function terminate($request, $response) { // In PHP-FPM, this runs after fastcgi_finish_request() // The client has already received their response $this->litesoc->flush(); } } // Register in app/Http/Kernel.php protected $middleware = [ // ... other middleware \App\Http\Middleware\FlushLiteSOCEvents::class, ];
Laravel Queued Jobs (Recommended for High-Traffic)
For high-traffic applications, dispatch events to a queue:
// app/Jobs/TrackSecurityEvent.php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use LiteSOC\LiteSOC; class TrackSecurityEvent implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable; public function __construct( public string $eventType, public array $options ) {} public function handle(LiteSOC $litesoc): void { $litesoc->track($this->eventType, $this->options); $litesoc->flush(); } } // Usage - non-blocking, runs in background queue worker TrackSecurityEvent::dispatch('auth.login_failed', [ 'actor_id' => 'user_123', 'user_ip' => request()->ip() ]);
API Reference
Event Collection API (/api/v1/collect)
| Method | Description |
|---|---|
track($eventName, $options) |
Queue a security event for sending |
trackLoginFailed($actorId, $options) |
Track failed login attempt |
trackLoginSuccess($actorId, $options) |
Track successful login |
trackPrivilegeEscalation($actorId, $options) |
Track privilege escalation (critical) |
trackSensitiveAccess($actorId, $resource, $options) |
Track sensitive data access |
trackBulkDelete($actorId, $recordCount, $options) |
Track bulk deletion operation |
trackRoleChanged($actorId, $oldRole, $newRole, $options) |
Track role/permission changes |
trackAccessDenied($actorId, $resource, $options) |
Track access denied events |
flush() |
Send all queued events immediately |
shutdown() |
Graceful shutdown with flush |
Events API (/api/v1/events)
| Method | Description |
|---|---|
getEvents($limit, $filters) |
List events with pagination |
getEvent($eventId) |
Get single event by ID |
Filters for getEvents():
event_name- Filter by event type (e.g.,auth.login_failed)actor_id- Filter by actor IDseverity- Filter by severity:critical,warning,infooffset- Pagination offset (default: 0)
Alerts API (/api/v1/alerts)
| Method | Description |
|---|---|
getAlerts($filters) |
List alerts with pagination |
getAlert($alertId) |
Get single alert by ID |
resolveAlert($alertId, $resolutionType, $notes) |
Mark alert as resolved |
markAlertSafe($alertId, $notes) |
Mark alert as safe/false positive |
Filters for getAlerts():
severity- Filter by severity:critical,warning,infostatus- Filter by status:active,resolved,safealert_type- Filter by type:impossible_travel,brute_force, etc.limit- Results per page (default: 20, max: 100)offset- Pagination offset (default: 0)
Resolution Types for resolveAlert():
blocked_ip- IP address was blockedblocked_user- User account was blockedfalse_positive- Alert was a false positiveinvestigated- Investigated, no action neededother- Other resolution
License
MIT License - see LICENSE for details.