Security
Authentication, authorization, mitigation safety, and operational hardening. This document is normative — anything that contradicts it in code is a bug.
1. Authentication
- bcrypt password hashes (
golang.org/x/crypto/bcrypt); cost default 10. - HS256 JWT issued by
/api/login, 8 h lifetime, signed withARPG_JWT_SECRET - Tokens are returned in the login response and sent as
Authorization: Bearer <jwt> - A 401 from any API call forces the SPA to logout and reload.
(crypto/hmac stdlib).
on every protected request.
`ARPG_JWT_SECRET` must be set at process start, ≥ 32 random bytes. If unset, the API will refuse to start in production (lab fallback is a deterministic dev secret — do not ship that). Rotating the secret invalidates all sessions; users must sign in again.
2. Authorization (RBAC)
Roles, low → high:
| Role | What it can do |
|---|---|
viewer |
Read‑only: dashboard, incidents, segments, sensors, binding DB, audit |
analyst |
viewer + acknowledge / quarantine / release incidents |
responder |
analyst + add / delete / edit bindings |
admin |
responder + users, policies, settings, change passwords |
Source of truth: the API server (backend/api/auth.go::requiredRole()). The dashboard's can(role) only hides UI for clarity — it is not a security boundary. Removing the gate client‑side does nothing the server doesn't already permit.
Demo accounts (created on first API start) are not production‑safe — rotate immediately.
3. Bootstrap
- First start reads
ARPG_ADMIN_PASSWORDand createsadminwith that bcrypt hash. - Demo accounts
analyst/analyst123,responder/responder123,viewer/viewer123are
created once for lab demos. Disable or rotate them before exposing the API outside the lab.
4. Mitigation safety invariants
These constraints are enforced in backend/correlator/mitigate.go and must remain true:
- Auto‑mitigation requires a deterministic Tier‑1 or Tier‑2 hit. Tier‑3 anomaly /
- Reversible by default. Every mitigation row has a
revert_ts; the controller - Circuit breaker. More than N actions per minute (configurable; lab default 10)
- Tamper‑evident audit. Every action writes to
mitigation_auditwithrecord_hash - Mode is per‑segment. A
MONITORsegment never auto‑acts even if the global mode
storm / ML‑shadow never auto‑blocks. They raise severity for human review.
auto‑reverts when it expires unless the threat is re‑observed.
trips to alert‑only until an operator resets it. Never bypass.
chaining the previous row. Out‑of‑order or missing hashes indicate tampering.
says ENFORCE. Operator policy wins.
5. Threat model (summary)
| Threat | Mitigation | Residual risk |
|---|---|---|
| Classic ARP poisoning (T1557.002) | Tier 1/2 deterministic detection + L1 corrective ARP | Vendor virtual MACs not in the allow‑list can produce FPs — manage the table |
| Gratuitous ARP storm | Tier 3 EWMA; correlator escalates to incident | Tier 3 alone does not block; analyst review required |
| Compromised analyst account | Per‑role gating + audit | An analyst can quarantine — rotate creds on suspected compromise |
| Compromised admin account | Same audit + offline log review | Admin can flip mode to MONITOR to suppress action — monitor settings changes |
| Stolen JWT | 8 h TTL + JWT‑secret rotation | Rotate ARPG_JWT_SECRET on suspected compromise (invalidates all sessions) |
| API host compromise | Defense in depth via NAC / network policy; this product is not a host‑hardening tool | A root attacker on the API host can issue arbitrary bindings — protect that host |
| Sensor false positive blocking gateway | Baseline accuracy + protected‑binding flag + circuit breaker | Lab gateway MAC must match reality (see baseline_sync) |
| vMAC mimicry by attacker on HA segment | Tier 2 cross‑reference to vmac_allowlist + DHCP corroboration |
RFC 826 has no source authentication — accept this as documented gap |
Detailed reasoning lives in the external archive at ../arpocalypse-2.0-docs/research/architecture/threat-model.md. This repo doesn't carry it.
6. Frontend hardening
- No external CDNs at runtime. Every vendor asset is npm + bundled by Vite. A 403 in
- JWT in localStorage is convenient but vulnerable to XSS. The dashboard escapes user
- CSP (recommended for production deploys):
default-src 'self'; img-src 'self' data:;
the dashboard always means a <script src="…unpkg/jsdelivr/cdnjs…"> slipped back in; remove it.
input by default (React JSX). Don't introduce dangerouslySetInnerHTML.
the build does not require external origins.
7. Network‑level controls (out of scope but worth noting)
- DHCP snooping + Dynamic ARP Inspection on switches gives you a second authoritative
- NAC / 802.1X integration is what makes L2 (NAC/CoA quarantine) actuator work. Without it,
binding table — pair it with this platform's bindings for defense in depth.
ENFORCE mode falls back to L1 corrective ARP.
8. What this platform is NOT
- It is not a host IDS. It does not protect a host against an attacker already on it.
- It is not a substitute for switch hardening. ARP integrity at the switch (DAI) is
- It is not authenticated at the protocol layer. ARP itself has no source
cheaper, faster and harder to bypass than any in‑band tool. Use both.
authentication — see RFC 826 § "Limitations". This platform raises detection coverage and enables fast reversible response; it does not replace IPSec/802.1X for endpoint identity.
9. Reporting issues
For research / responsible‑disclosure issues against this codebase, open an issue with the security label. Do not include reproduction details for actively exploitable bugs in the issue body — request a private channel first.