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 with ARPG_JWT_SECRET
  • (crypto/hmac stdlib).

  • Tokens are returned in the login response and sent as Authorization: Bearer <jwt>
  • on every protected request.

  • A 401 from any API call forces the SPA to logout and reload.

`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_PASSWORD and creates admin with that bcrypt hash.
  • Demo accounts analyst/analyst123, responder/responder123, viewer/viewer123 are
  • 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:

  1. Auto‑mitigation requires a deterministic Tier‑1 or Tier‑2 hit. Tier‑3 anomaly /
  2. storm / ML‑shadow never auto‑blocks. They raise severity for human review.

  3. Reversible by default. Every mitigation row has a revert_ts; the controller
  4. auto‑reverts when it expires unless the threat is re‑observed.

  5. Circuit breaker. More than N actions per minute (configurable; lab default 10)
  6. trips to alert‑only until an operator resets it. Never bypass.

  7. Tamper‑evident audit. Every action writes to mitigation_audit with record_hash
  8. chaining the previous row. Out‑of‑order or missing hashes indicate tampering.

  9. Mode is per‑segment. A MONITOR segment never auto‑acts even if the global mode
  10. 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
  • the dashboard always means a <script src="…unpkg/jsdelivr/cdnjs…"> slipped back in; remove it.

  • JWT in localStorage is convenient but vulnerable to XSS. The dashboard escapes user
  • input by default (React JSX). Don't introduce dangerouslySetInnerHTML.

  • CSP (recommended for production deploys): default-src 'self'; img-src 'self' data:;
  • 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
  • binding table — pair it with this platform's bindings for defense in depth.

  • NAC / 802.1X integration is what makes L2 (NAC/CoA quarantine) actuator work. Without it,
  • 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
  • cheaper, faster and harder to bypass than any in‑band tool. Use both.

  • It is not authenticated at the protocol layer. ARP itself has no source
  • 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.