ExfilGuardian
Backend

Backend

All-Rust distributed anti-exfiltration backend architecture

Overview

ExfilGuardian is an all-Rust anti-exfiltration detection system built on a distributed three-tier architecture: Driver (Ring 0), Agent (Ring 3), Server (Cloud/On-Prem). Windows is the primary target, with Linux support planned. There is no C code in the project. Memory safety is enforced from the kernel driver to the cloud server through Rust's ownership model.

Workspace Structure

The project is organized as a Cargo workspace with five crates, plus a separate standalone workspace for the kernel driver:

CrateTypeLocationToolchainDescription
exfil-agentBinaryagent/StableWindows service, DeviceIoControl, SQLite queue, gRPC client
exfil-serverBinaryserver/StableDual server (gRPC + REST), analysis pipeline
exfil-analysisLibraryanalysis/StableDetection engine: DPI, signatures, behavioral, correlation
exfil-installerBinaryinstaller/StableRegistry config, sc.exe service creation
exfil-certs-genBinarycerts/StableCA/server/agent certificate generation via rcgen
(driver)WDM driverdriver/Nightly#![no_std] WFP kernel driver (separate workspace, Windows-only build)

Workspace Dependencies

All shared dependencies are defined in the root Cargo.toml under [workspace.dependencies] and referenced with .workspace = true in each crate:

# Root Cargo.toml
[workspace]
members = ["agent", "server", "analysis", "installer", "certs"]

[workspace.dependencies]
tokio = { version = "1", features = ["full"] }
tonic = "0.12"
prost = "0.13"
serde = { version = "1", features = ["derive"] }
anyhow = "1"
thiserror = "2"

The driver crate (driver/) maintains its own Cargo.toml and builds with the nightly toolchain because it requires #![no_std], the WDK allocator, and unstable features for kernel-mode Rust.

Protocol Definition

Agent-to-server communication is defined in proto/exfil.proto:

service ExfilService {
  rpc StreamPackets(stream NetworkPacket) returns (StreamResponse);
}

message NetworkPacket {
  uint32 protocol    = 1;  // IANA protocol number (6=TCP, 17=UDP, 1=ICMP)
  uint32 local_ip    = 2;  // Source IP (big-endian)
  uint32 remote_ip   = 3;  // Destination IP (big-endian)
  uint32 local_port  = 4;
  uint32 remote_port = 5;
  uint64 timestamp   = 6;  // Unix timestamp in milliseconds
  bytes  payload     = 7;  // Raw L7 application data
  string auth_token  = 8;  // Agent authentication token
}

Error Handling Conventions

  • thiserror for library errors (analysis crate)
  • anyhow for application errors (agent, server, installer crates)
  • Never use unwrap() in production code; always propagate with ?

Sub-pages

  • Kernel Driver: WFP driver architecture, DKOM bypass, anti-kill, registry protection
  • Analysis Engine: DPI, signatures, behavioral analysis, correlation pipeline
  • API: gRPC ingestion (tonic) and REST dashboard (axum)
  • Agent & Installer: Windows service, DeviceIoControl loop, SQLite WAL, deployment
  • Signatures: YAML detection rules format, operators, fields, and hot-reload
  • Contributor Guide: Where to code each feature, development roadmap

On this page