Skip to content

Releases: lance0/prefixd

v0.14.1

03 Apr 18:11

Choose a tag to compare

Fixed

  • Prometheus metrics wired up — All event, mitigation, announcement, reconciliation, guardrail, and BGP session metrics were defined but never incremented. Now properly instrumented across all handler and reconciliation paths. (contributed by @bswinnerton)
  • MITIGATIONS_ACTIVE gauge — Reconciliation loop now recomputes with correct action_type and pop labels each tick
  • BGP_SESSION_UP gauge — Updated each reconciliation tick from actual peer session state

Security

  • aws-lc-sys 0.36.0 → 0.39.1 — CRL scope check logic error (high), PKCS7 signature/cert chain bypass (high), AES-CCM timing side-channel (medium), X.509 name constraints bypass
  • rustls-webpki 0.103.9 → 0.103.10 — CRL Distribution Point matching logic
  • picomatch → 4.0.4 — ReDoS via extglob quantifiers (high), method injection in POSIX character classes (moderate)

Dependencies

  • uuid 1.21.0 → 1.22.0
  • rustls 0.23.36 → 0.23.37
  • ipnet 2.11.0 → 2.12.0
  • @radix-ui/react-popover 1.1.4 → 1.1.15
  • recharts 3.7.0 → 3.8.0

Full Changelog: v0.14.0...v0.14.1

v0.14.0

20 Mar 01:18

Choose a tag to compare

What's New

Multi-Signal Correlation Engine

Combine weak signals from multiple detectors into high-confidence mitigation decisions. Events targeting the same (victim_ip, vector) within a time window are grouped into signal groups with configurable source weights, corroboration thresholds, and per-playbook overrides.

  • Signal groups with derived confidence, source counting, and corroboration status
  • Correlation explainability on mitigations (why a decision was made)
  • Per-playbook overrides for min_sources and confidence_threshold
  • Signal group expiry via the reconciliation loop

Signal Adapters

  • Alertmanager webhook (POST /v1/signals/alertmanager) — maps labels/annotations to attack events, handles batched alerts, resolved alerts trigger withdraw, fingerprint dedup
  • FastNetMon webhook (POST /v1/signals/fastnetmon) — classifies vector from traffic breakdown, configurable confidence mapping, attack_uuid dedup

Correlation Config API

  • GET /v1/config/correlation — current config (secrets redacted)
  • PUT /v1/config/correlation — update config (admin only, validates, writes YAML, hot-reloads)

Correlation Dashboard

  • Correlation page with Signals, Groups, and Config tabs
  • Signal group detail page with contributing events and source breakdown
  • Correlation context section on mitigation detail page

Infrastructure

  • Docker configs mount changed from read-only to writable (dashboard config editors work out of the box)
  • Default configs/correlation.yaml included as example config

Documentation

Testing

  • 179 backend unit tests, 99 integration, 16 postgres, 9 e2e, 64 frontend
  • All passing, clippy clean, Docker containers verified end-to-end

Breaking Changes

None. Correlation is opt-in via correlation.enabled: true. Default behavior preserves existing single-source flow.

Full Changelog: v0.13.0...v0.14.0

v0.13.0

19 Mar 17:04

Choose a tag to compare

What's New

  • Event batchingPOST /v1/events/batch accepts up to 100 events in a single request with partial success semantics (202/207). Sequential processing through the full pipeline (validation, guardrails, policy, FlowSpec announce).

  • Post-attack incident reportsGET /v1/reports/incident?mitigation_id=X or ?ip=X generates a markdown incident report with summary table, timeline, events, mitigations, and audit trail. Dashboard "Report" buttons on mitigation detail and IP history pages with copy/download dialog.

  • FlowSpec NLRI fuzz/property tests — 8 proptest property-based tests for prefix parsing, NLRI roundtrip, and action roundtrip. Two cargo-fuzz targets for offline fuzzing with libFuzzer.

Bug Fixes

  • WebSocket rejected all connections when auth_mode is none — Dashboard showed "Disconnected" permanently in no-auth deployments.
  • Mitigation detail page showed "Not Found" on Next.js 16 — Dynamic route params became async in Next.js 15+.
  • Dark mode outline button hover invisible — Export CSV, Refresh, and other outline-variant buttons had nearly invisible hover states in dark mode.

Full Changelog: v0.12.0...v0.13.0

v0.12.0

18 Mar 19:30

Choose a tag to compare

What's New

  • Cursor-based pagination — All list endpoints now use cursor-based pagination (?cursor=<opaque>&limit=N). Responses include next_cursor and has_more fields. Breaking: offset parameter removed (see ADR 016).
  • Date range filtering — All list endpoints accept ?start=<ISO8601>&end=<ISO8601> for time-bounded queries.
  • Bulk acknowledgePOST /v1/mitigations/acknowledge marks mitigations as reviewed (sets acknowledged_at/acknowledged_by). Filterable via ?acknowledged=true|false.
  • Per-destination event routing — Each alerting destination can specify its own events list to override the global filter. Backward-compatible (ADR 017).
  • Notification preferencesGET/PUT /v1/preferences stores per-operator toast settings (muted events, quiet hours UTC). Dashboard toasts respect preferences; quiet hours suppress non-critical events only.

Breaking Changes

Offset pagination removed

?offset=N no longer works on /v1/mitigations, /v1/events, or /v1/audit. Use cursor-based pagination:

# Page 1 (no cursor = first page)
curl '/v1/mitigations?limit=50'
# Response: {"mitigations": [...], "next_cursor": "MjAyNi0w...", "has_more": true}

# Page 2
curl '/v1/mitigations?limit=50&cursor=MjAyNi0w...'

If you use prefixdctl, replace --offset with --cursor.

Audit response shape changed

GET /v1/audit now returns {"entries": [...], "count": N, "next_cursor": ..., "has_more": ...} instead of a bare array.

Migrations

Two new migrations run automatically on startup:

  • 005: acknowledged_at/acknowledged_by columns on mitigations
  • 006: notification_preferences table

Back up your database before upgrading: docker compose exec postgres pg_dump -U prefixd prefixd > backup.sql

Bug Fixes

  • Migration 005 uses IF NOT EXISTS for idempotent column adds
  • Notification preferences: quiet hours always serialized as explicit null
  • Half-configured quiet hours rejected (both start and end required, or both null)
  • Preferences fetched eagerly on session start
  • Bun pinned to 1.3.10 in Dockerfile (1.3.11 segfaults during next build in CI)

See upgrading.md for detailed migration guide.

Full Changelog: v0.11.0...v0.12.0

v0.11.0

18 Mar 13:09

Choose a tag to compare

What's New

  • Bulk withdrawPOST /v1/mitigations/withdraw accepts up to 100 mitigation IDs with partial success semantics. Frontend adds checkbox selection on active/escalated rows, select-all, selection toolbar, and confirmation dialog. Critical during false-positive waves.
  • FlowSpec rule preview — Mitigation detail page shows a router-style one-liner (match destination 203.0.113.10/32 protocol udp destination-port 53 then rate-limit 5 Mbps) above the structured grid. Copy Rule button for quick comparison with router CLI output.
  • CVE gate in CI — Security audit (cargo audit + bun audit) now gates Docker publishing. CycloneDX SBOM generated as a release artifact on version tags.
  • Vendor capability matrix — New docs/vendors.md with tested status for Juniper (verified), Arista (partially verified via community production deployment), Cisco IOS-XR, Nokia SR OS, and FRR. Reference import policies per vendor.

Security

  • Next.js — Updated to 16.1.7 (CSRF bypass, HTTP smuggling, disk cache DoS, postpone DoS)
  • undici — Updated to 7.24.4 (WebSocket overflow, request smuggling, memory DoS, CRLF injection)
  • quinn-proto — Updated to 0.11.14 (RUSTSEC-2026-0037, DoS in Quinn endpoints)
  • rollup — Updated to 4.59.0 (GHSA-mw96-cpmx-2vgc, arbitrary file write)

Dependencies

16 dependency updates including tonic 0.14.5, futures-util 0.3.32, Next.js 16.1.7, and 5 GitHub Actions major version bumps.

Full Changelog: v0.10.1...v0.11.0

v0.10.1

22 Feb 04:58

Choose a tag to compare

Bug Fixes

  • FastNetMon re-ban collision — Deterministic sha256(IP|direction) event IDs caused permanent 409 duplicates after withdrawal. The integration script now uses UUID event IDs per ban occurrence, enabling re-ban and proper TTL extension for ongoing attacks. (#65)
  • FastNetMon unban flow — Unban now queries active mitigations by victim_ip and withdraws directly, with a configurable retry window for ban/unban race timing. (#65)
  • FastNetMon withdraw missing operator_id — Withdraw payload now includes PREFIXD_OPERATOR (default: fastnetmon) to satisfy API validation.

Added

  • victim_ip filter on mitigations APIGET /v1/mitigations?victim_ip=X filters by exact victim IP address. Supported in both single-POP and all-POPs queries.
  • FastNetMon integration guide — New docs/detectors/fastnetmon.md with full setup, env vars, testing, and troubleshooting.

Full Changelog: v0.10.0...v0.10.1

v0.10.0

22 Feb 02:36

Choose a tag to compare

What's New

  • Playbook editor — Edit playbooks directly from the dashboard with a form-based editor or raw YAML tab. PUT /v1/config/playbooks endpoint with full validation, atomic write with backup, and hot-reload.
  • Interactive alerting config — Add, edit, and remove alert destinations from the dashboard. PUT /v1/config/alerting endpoint with secret merge (existing secrets preserved via *** sentinel), atomic write to standalone alerting.yaml, and hot-reload. Type-specific forms for all 7 destination types with event filter checkboxes.
  • Alerting config split — Alerting configuration moved from prefixd.yaml to standalone alerting.yaml with backward-compatible fallback.
  • Event cross-links — Mitigation detail page shows clickable links to triggering and last (TTL extend) events.
  • GHCR Docker publishing — CI publishes prefixd and prefixd-dashboard images to ghcr.io/lance0/prefixd and ghcr.io/lance0/prefixd-dashboard.

Security

  • SSRF protection on webhook URLs (HTTPS required, localhost/private IPs rejected)
  • Secret merge ambiguity detection (errors on multiple same-type destinations)
  • Atomic config writes with symlink rejection for both playbooks and alerting
  • Concurrent write serialization across merge/validate/save/swap
  • reload_config() race fix (write locks held during load+swap)

Test Coverage

  • 116 backend unit tests, 25 integration tests, 26 frontend tests
  • No database migrations required
  • No breaking API changes

Full Changelog: v0.9.1...v0.10.0

v0.9.1

21 Feb 15:31

Choose a tag to compare

What's New

Webhook Alerting Backend

7 destination types: Slack (Block Kit), Discord (embeds), Microsoft Teams (Adaptive Card), Telegram (Bot API), PagerDuty (Events API v2 with auto-resolve), OpsGenie (Alert API v2), Generic webhook (HMAC-SHA256 signed). Fire-and-forget dispatch with bounded concurrency (64 tasks), 3 retries with exponential backoff.

New endpoints: GET /v1/config/alerting (secrets redacted), POST /v1/config/alerting/test (admin-only).

Dashboard Quick Wins

  • Alerting config UI — New tab on Config page with destination list and "Send Test Alert" button
  • Audit log detail expansion — Click to expand full JSON details inline
  • Customer/POP filters — Dropdown filters on mitigations page
  • Timeseries range selector — 1h/6h/24h/7d toggle on activity chart
  • Active count badge — Live mitigation count on sidebar nav
  • Severity badges — Color-coded severity column on mitigations table

Testing Infrastructure

  • Chaos test suite (17 tests: Postgres/GoBGP/prefixd kill, network outage)
  • HTTP load test suite (7 tests: ~4,700 events/sec, ~8,000 health req/s)
  • Benchmarks documentation with micro-benchmark and HTTP load test baselines

Security

  • Login brute-force throttle hardened (atomic check, bounded state, TTL pruning)
  • Generic webhook header values redacted in API response
  • CIDR validation uses ipnet::IpNet (rejects invalid masks like /999)
  • Alerting test endpoint restricted to admin role
  • CSV formula sanitization regex strengthened
  • Alert task queue bounded at 64 concurrent tasks
  • Input validation on operator_id, withdraw reason fields

Changed

  • 93 backend unit tests (up from 73), 26 frontend tests
  • OpenAPI spec includes alerting endpoints
  • Load/chaos scripts support PREFIXD_API_TOKEN for authenticated environments

Full Changelog: v0.9.0...v0.9.1

v0.9.0

21 Feb 01:39

Choose a tag to compare

What's New

Embedded Charts & IP History

  • 24h activity chart on the overview page — area chart showing mitigations and events per hour, backed by PostgreSQL generate_series gap-filled buckets
  • IP history page (/ip-history?ip=X) — unified timeline of all events and mitigations for an IP with customer/service context from inventory
  • Clickable IPs everywhere — all victim_ip cells link to IP history; added to sidebar, command palette (g h), keyboard shortcuts

Observability

  • Database pool metricsprefixd_db_pool_connections{state=active|idle|total} gauge on each /metrics scrape
  • Request correlation IDsx-request-id header (UUID) preserved or generated per request, echoed in response, added to tracing span, forwarded by nginx
  • Reconciliation active countprefixd_reconciliation_active_count gauge tracks mitigations seen during drift detection

v1.0 Stability

  • Reconciliation loop pagination — pages through all active mitigations (was capped at 1000)
  • Database migration trackingschema_migrations table with prefixdctl migrations command
  • API versioning policydocs/api-versioning.md with backward compat guarantees and Sunset header convention
  • Upgrade guidedocs/upgrading.md with Docker Compose and bare metal procedures, rollback guidance

Production Deployment

  • HTTPS via nginx — full TLS termination example with HSTS, HTTP→HTTPS redirect, Let's Encrypt note
  • Mitigate Now modal — replaced full page with dialog overlay; command palette n shortcut opens it directly

Bug Fixes

  • Timeseries sub-hour bucketingdate_trunc('hour') replaced with date_bin() for correct 5m/30m alignment
  • Frontend TypeScript types — recharts 3.7 tooltip/legend, resizable-panels API, badge prop types
  • CLI/docs drift — fixed stale endpoint paths, removed references to nonexistent commands
  • CSV export crash — fixed wrong field name on events page
  • Nested anchor in active-mitigations-mini fixed (accessibility)
  • IP validation/v1/ip/{ip}/history now returns 400 on invalid input

Test Coverage

  • 73 unit tests, 15 integration tests, 9 postgres tests, 25 frontend tests
  • New: IP history validation, timeseries bucket alignment regression test

Full Changelog: v0.8.5...v0.9.0

v0.8.5

20 Feb 03:03

Choose a tag to compare

What's New

Cross-Entity Navigation

  • Activity feed clickable items -- Event and mitigation entries on the overview page now link to their detail pages
  • Vector breakdown chart -- Legend items link to mitigations filtered by that vector
  • Inventory cross-links -- Customer IDs and asset IPs link to mitigations search
  • Mitigations search enhanced -- Now matches on vector, customer_id, and mitigation_id (was IP-only)

Testing

  • Hook tests -- 10 new tests for usePermissions (auth disabled, admin/operator/viewer, deny-by-default) and useAuth (provider guard, login/logout, session expiry)
  • 21 frontend tests total (up from 11)

Dependency Upgrades

  • lucide-react 0.454 → 0.575
  • react-resizable-panels 2.1 → 4.6

Full Changelog: v0.8.4...v0.8.5