Events & Schema
Every signal Gatekeeper collects becomes a SecurityEvent, serialized to an Elastic Common Schema (ECS) 8.x JSON document. ECS is the wire format for all sinks: Wazuh ingests it natively as JSON, it maps cleanly onto Microsoft Sentinel custom tables, and analysts get the same field names everywhere.
Anatomy of an event#
{
"@timestamp": "2026-07-11T09:14:23.187Z",
"ecs": { "version": "8.11.0" },
"event": {
"id": "9c2f6f0a-6f4e-4d0b-9c1e-1c1a2b3c4d5e",
"kind": "event",
"module": "gatekeeper",
"dataset": "gatekeeper.security",
"category": ["intrusion_detection", "threat"],
"type": ["info"],
"action": "honeypot_route_hit",
"outcome": "failure",
"severity": 7
},
"message": "Honeypot route accessed",
"service": { "name": "shop", "environment": "production" },
"host": { "name": "web-01" },
"source": {
"ip": "203.0.113.9",
"geo": {
"country_iso_code": "NO",
"city_name": "Oslo",
"location": { "lat": 59.91, "lon": 10.75 }
}
},
"user_agent": { "original": "Mozilla/5.0 (compatible; scanner)" },
"url": { "path": "/wp-login.php", "full": "https://shop.example/wp-login.php" },
"http": { "request": { "method": "GET" } },
"threat": {
"framework": "MITRE ATT&CK",
"tactic": { "id": ["TA0043"], "name": ["Reconnaissance"] },
"technique": { "id": ["T1595.003"], "name": ["Active Scanning: Wordlist Scanning"] }
},
"labels": { "siem_event_type": "honeypot_route_hit", "siem_severity": "high" },
"laravel": {
"context": { "honeypot_path": "wp-login.php", "auto_blocked": true }
}
}
Key field groups:
| Fields | Purpose |
|---|---|
event.* |
What happened: action, category, outcome, numeric severity, unique ID |
source.ip, source.geo.* |
Who did it and from where (geo added by GeoIP enrichment) |
user.id, user.name |
The authenticated user involved, if any |
url.*, http.request.method, user_agent.original |
The request being made |
threat.* |
MITRE ATT&CK mapping for the behaviour |
service.*, host.name |
Which app/environment/host emitted it |
laravel.context |
Event-specific detail (thresholds crossed, probed IDs, trigger reasons, your custom context) |
Severity levels#
Gatekeeper uses six levels, mapped onto each destination's convention:
| Severity | ECS event.severity |
CEF | Syslog |
|---|---|---|---|
debug |
1 | 0 | 7 |
info |
2 | 2 | 6 |
low |
3 | 4 | 5 |
medium |
5 | 6 | 4 |
high |
7 | 8 | 3 |
critical |
9 | 10 | 2 |
Two severity filters exist:
events.minimum_severity(SIEM_MIN_SEVERITY) — global floor; events below it are dropped before shipping.- Per-sink
minimum_severity— e.g. Slack defaults tohigh, so the channel only receives pageable alerts while the full stream flows to the SIEM.
Event catalog#
event.action |
Severity | MITRE | Source |
|---|---|---|---|
login_succeeded |
info | T1078 Valid Accounts | auth listener |
login_failed |
low | T1110 Brute Force | auth listener |
logout |
info | — | auth listener |
user_registered |
info | — | auth listener |
password_reset_requested |
low | — | auth listener |
password_reset |
low | — | auth listener |
auth_lockout |
high | T1110 Brute Force | auth listener |
email_verified |
info | — | auth listener |
access_denied |
medium | — | your code (EventType::AccessDenied) |
honeypot_route_hit |
high | T1595.003 Wordlist Scanning | honeypot routes |
honeypot_form_triggered |
medium | — | siem.honeypot middleware |
brute_force_detected |
critical | T1110 Brute Force | siem.abuse middleware |
scanning_detected |
high | T1595.003 Wordlist Scanning | siem.abuse middleware |
rate_limit_abuse |
medium | T1595 Active Scanning | siem.abuse middleware |
endpoint_abuse |
high | T1595 Active Scanning | siem.abuse middleware |
suspicious_input |
high | T1190 Exploit Public-Facing App | siem.scan middleware |
resource_enumeration_detected |
high | T1119 Automated Collection | siem.enum middleware |
blocked_ip_attempt |
low | — | siem.block middleware |
ip_blocked |
medium | — | blocklist |
egress_new_destination |
medium | T1071 Application Layer Protocol | egress monitoring |
egress_spike_detected |
high | T1496 Resource Hijacking | egress monitoring |
egress_limit_exceeded |
high | T1496 Resource Hijacking | egress monitoring |
egress_error_spike |
medium | T1499 Endpoint DoS | egress monitoring |
| anything | your choice | — | Siem::log() / Siem::event() |
Authentication monitoring#
Gatekeeper subscribes to Laravel's native auth events automatically — no code changes needed. Whatever fires Illuminate\Auth\Events\* (the standard guards, Fortify, Breeze, Jetstream) is covered:
| Laravel event | Gatekeeper event |
|---|---|
Login |
login_succeeded (guard + remember flag in context) |
Failed |
login_failed (attempted identifier in context; password never captured) |
Logout |
logout |
Registered |
user_registered |
PasswordReset |
password_reset |
Lockout |
auth_lockout |
Verified |
email_verified |
Each is individually toggleable under events.authentication, and the whole subscriber can be disabled with SIEM_EVENTS_AUTH=false.
Event flow#
- A monitor (listener, middleware, honeypot, or your code) builds a
SecurityEvent. - The manager applies the global severity floor, scrubs context through the redactor, and serializes to ECS.
- For each active sink that accepts the event's severity, a
ShipEventjob is dispatched to thesiemqueue. - On the worker, the document is GeoIP-enriched and handed to the sink. Failures retry 3 times with backoff (5s / 30s / 120s), then fall back to the local Laravel log with the full event attached.