Overview — what it does
Security Overview (/security) is the centerpiece of the security role area. It surfaces the "hidden telemetry" that InfraGuard already collects, judges, and auto-mitigates — but that had never been visualized — as a single defense-funnel narrative.
The core message is one sentence: "Right now, AI + IDS auto-defense is blocking hostile networks." To make that credible, the screen shows at a glance:
- 4-stage defense funnel — threat (raw events) → detection (flags) → auto-response ruleset (catalog rules + JA3 rulesets) → response (blocks). Each stage carries a measured count.
- Threat-intensity gauge — a conic donut derived from the security score (higher = more dangerous).
- Auto-response cards — threats/hour, 24h threats, active blocks /24, 24h blocks.
- JA3 offenders panel — top JA3-fingerprint offenders over the last 6 hours (automation / botnet candidates).
- Top threat IPs + recent auto-action feed (the "why we blocked" narrative).
- Threat-trend sparkline over the selected window.
Everything is read-only — this screen never blocks or edits anything. Actual operations happen on Threats, Blocklist & Reputation, and Detections.
There is no "domain" here — Security Overview is a summary by role area (security operations), not by web TLD.
When to use
- At shift start to grasp the whole security posture in 30 seconds.
- To credibly explain to management/auditors that blocking actually works (funnel counts + automation ratio).
- To spot a threat spike on the trend sparkline, then pick a suspicious IP and drill into Threats / Detections.
- To quickly scan JA3 botnets/scanners and jump to the detailed rulesets.
Layout
Top — threat-intensity gauge + defense funnel
| Area | Content |
|---|---|
Threat intensity (t.ov.score) |
Security score rendered as a conic-gradient donut. Displayed value = 100 − score (higher = worse). Subtitle: "higher = more dangerous, based on what was left unmitigated". |
Defense funnel (t.ov.funnel_title) |
Four stage bars narrowing top-to-bottom, each with a measured count and a caption. |
Middle — auto-response + threat trend
| Card | Content |
|---|---|
Auto-response (t.ov.resp_title) |
Four metric tiles: threats/hour · 24h threats · active blocks /24 · 24h blocks. |
Threat trend (t.ov.tseries_title) |
An SVG sparkline of IDS alerts downsampled into 30 buckets, with a Σ total · ▲ max/bucket-min meta and a collection-lag (⏱ Nm) badge. |
Bottom — JA3 offenders · top threat IPs · recent auto-actions
- JA3 sequence analysis (
t.ov.ai_title) — top offenders over the last 6 hours as a 3×3 grid (up to 9 cards). Each card shows JA3 variety · TLS connections · SNI variety · country/ASN/ISP · a "blocked" badge, plus a rotation bar and a behaviour tag picked in the browser fromt.ov.ai_behavior(so it follows the reader's language). Clicking an IP opens the reputation popup; the rulesets themselves live in Detections. - Top threat IPs (
t.ov.top_title) — alerts · severity · distinct signatures · last seen · blocked flag · country. - Recent auto-actions (
t.ov.feed_title) — recently blocked /24 ranges with country · source tag (Kitsune/Suricata/manual) · short reason · timestamp.
Header controls
- Window toggle:
1h / 6h / 24h(default 24h). - LIVE / PAUSED toggle: turns the 30-second auto-poll on/off.
- Fullscreen button: hides the top nav for a dashboard mode (ESC exits).
- stamp: the last computation time.
How to use
- Read the top threat-intensity gauge for the current risk level (bigger = worse).
- Read the defense funnel top-to-bottom to follow the story: "how many came in (threat) → how many were flagged (detection) → how many rulesets fired (auto-response) → how many were blocked (response)".
- Look at the threat-trend sparkline for spikes. A large
⏱ Nmbadge means collection is lagging, so interpret counts as of that anchor time. - Pick a suspicious IP from JA3 offenders / top threat IPs, then move to Threats / Detections for deep investigation, reputation lookup, and blocking.
- Use the recent auto-action feed to see what auto-defense just blocked and why.
Exact definition of the funnel stages
Every count is scoped to the selected window (1h/6h/24h). SecurityOverviewService::compute() produces them.
| Stage | Key | Formula | Source |
|---|---|---|---|
| Threat | threats |
alertCount + nginxSuspiciousCount |
suricata_alert_ct + nginx_meta_ct (is_suspicious=1) |
| Detection | detections |
distinctAlertIps + kitsuneBlockedCount |
distinct src_ip (suricata_alert_ct) + kitsune_detail_log (is_blocked=1) |
| Auto-response ruleset | rulesets |
active rulesets + firing rulesets |
infr_sec_ruleset (status=active) + firing among the 44-ruleset catalog |
| Response | response |
blockedCount |
blacklist_info (created_at ≥ window) |
The "auto-response ruleset" count is NOT the number of raw signatures (sid). It is counted in the same "ruleset" unit as the Rulesets library (RulebookService is reused), so it never exceeds the 44-item catalog and matches the Rulesets screen.
Auto-response card metric definitions
| Metric | Meaning | Computation |
|---|---|---|
| Threats/hour | threats_hr |
anchor-based 24h alerts ÷ 24 |
| 24h threats | threats_24h |
anchor-based 24h alertCount |
| Active blocks /24 | active |
count of blacklist_info where is_use=1 |
| 24h blocks | blocks_24h |
last-24h blockedCount |
The auto-response section also carries copy for "isolate (auto)" and "international cooperation (manual)" (
resp.isolate/resp.coop), but those two are a later phase counted after response tooling is deployed — today only the four metrics above are actually computed.
Threat-intensity (security score) formula
The formula is owned by Services\Security\PostureService (revised 2026-09-04). It is the same number the Overview "security basis" card shows:
score = weighted mean of ids, ai, web, rep, tls, fw # each metric 0..100
metric = 100 − 45 × open / (total + floor) # open = 0 -> metric = 100
displayed threat intensity = 100 − score # 0..45, higher = worse
open= what we failed to stop,total= everything of that kind observed (blocked included), floor = a smoothing constant so a tiny sample cannot blow the ratio up.- A residue of zero scores the metric at 100 — however heavily you were attacked, stopping all of it is not a reason to deduct.
- Mitigation counts both
blacklist_info(enforced) andblacklist(staged). Your own network ranges are removed from numerator and denominator alike. - The old formula deducted for
kitsune_detail_logblock counts andnginx_meta_ctsuspicious requests, so the score fell as auto-defense succeeded. - The score is clamped to a floor of 55 (= threat intensity max 45).
Data sources
All threat/detection/block counts read the large telemetry tables on the legacy legacy_glory connection, read-only. Credentials come only from config('database.connections.legacy_glory') (= .env) and are never hardcoded.
| Table | Connection | Use |
|---|---|---|
suricata_alert_ct |
legacy_glory | IDS alerts (threat, detection, top threat IPs, trend). alert_ts index |
nginx_meta_ct |
legacy_glory | suspicious web requests (is_suspicious). idx_suspicious |
kitsune_detail_log |
legacy_glory | ML anomaly blocks (is_blocked) |
suricata_tls_ct |
legacy_glory | JA3 fingerprint sequences (JA3 offenders) |
blacklist_info |
legacy_glory | auto/manual blocks (/24 CIDR). response, active blocks, feed |
ip_info_loop |
legacy_glory | geo/ASN/ISP enrichment (ipEnrichment) |
infr_sec_ruleset |
app (MAIN) | JA3 sequence rulesets (active-ruleset count + summary) |
Performance & freshness discipline
- Queries use narrow time windows + indexes + LIMIT only (to avoid slow queries on huge tables).
SecurityRepositoryisolates them with the query builder and parameter binding. - Anchor = latest alert time (
latestAlertTs()=MAX(alert_ts)). Whennow()runs ahead of the data because eve_ingest lagged, the time series and 24h stats are anchored here to remove the "empty tail". Lag over 5 minutes is shown as a⏱ Nmbadge. - 30-second cache: results are cached for 30 seconds under key
infr:sec:ov:{range}to match the 30-second poll. Individual read failures are absorbed bysafe(), so one broken area does not stall the whole funnel.
SecurityScope — automatic self-net exclusion
The top-threat-IP and JA3-offender lists automatically exclude your own network so your servers do not appear as attackers (no hardcoding).
SecurityScope::excludePrefixes()merges registered instances (infr_instancepublic/private/NIC IPs → /24 prefix) with the operations-policy whitelist (internal_networks— IPs, prefixes, CIDRs) into a prefix array.- Those prefixes are applied in the query as
src_ip NOT LIKE 'prefix%'(parameter-bound). - The matcher is cached for 60 seconds and invalidated whenever Operations Policy is saved.
e.g. register 203.0.113.10 in infr_instance → prefix "203.0.113." auto-excluded
add 10.0.0.0/8 to OpsPolicy internal_networks → CIDR → "10." coarse prefix excluded
If your own servers keep appearing in threats/offenders, register those IPs under Assets ▸ Instances or add them to the
internal_networkswhitelist in Operations Policy. They drop off automatically.
Access
- The entire
/security/*area, including this screen, is protected by theinfr.level:2middleware — you needuser_level ≥ 2to enter. - So a demo (1) account is blocked from security data, while staff (5) and admin (10) can view it.
- Security Overview is fully read-only — there are no write / block / edit actions, so it needs no step-up gate or audit logging. Actual block/release happens on Blocklist & Reputation (write level ≥ 2 + audit).
Troubleshooting & FAQ
Q. All funnel counts are 0.
The selected window (1h/6h/24h) may have no data, or the legacy_glory connection may be down. Widen to 24h; if the ⏱ lag badge is very large, a collector (eve_ingest / kts_tx / srct_tx) has stalled and the data is stale.
Q. Our own server IP shows up in top threats/offenders.
Self-net exclusion is not covering it. Register that IP under Instances or add it to internal_networks in Operations Policy (SecurityScope excludes by /24 prefix).
Q. The "auto-response ruleset" number differs from the Rulesets library.
The ruleset stage is active rulesets + firing rulesets. Active JA3 sequence rulesets (infr_sec_ruleset active) are added, so it can exceed pure catalog firing count.
Q. A ruleset says action=block, but nothing was blocked.
That field is a recommendation, not an instruction. Auto-block computes JA3 rotation directly from suricata_tls_ct and never reads infr_sec_ruleset; actual blocking happens from Blocklist or the auto-block scheduler. See Detections.
Q. Threat intensity is always low (≤45).
That is expected. The displayed value is 100 − score, and score is clamped to a floor of 55, so threat intensity ranges 0..45.
Q. Numbers jitter slightly every 30 seconds. That is the 30-second poll + 30-second cache combination recomputing over the latest window each poll. Turn off LIVE to stop auto-refresh.
Related
- Threats — IDS threat-entity triage, IP drilldown, block linkage.
- Detections + JA3 — detector algorithm narrative and JA3 sequence rulesets (on-demand analysis).
- Rulesets library — the 44 detection-ruleset catalog (canonical source of the firing count).
- Blocklist & Reputation — blacklist_info auto-defense narrative + block/release controls.
- Operations Policy —
internal_networkswhitelist (SecurityScope self-net exclusion). - IP reputation lookup — AbuseIPDB in-app popup.

