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:
| Crate | Type | Location | Toolchain | Description |
|---|---|---|---|---|
exfil-agent | Binary | agent/ | Stable | Windows service, DeviceIoControl, SQLite queue, gRPC client |
exfil-server | Binary | server/ | Stable | Dual server (gRPC + REST), analysis pipeline |
exfil-analysis | Library | analysis/ | Stable | Detection engine: DPI, signatures, behavioral, correlation |
exfil-installer | Binary | installer/ | Stable | Registry config, sc.exe service creation |
exfil-certs-gen | Binary | certs/ | Stable | CA/server/agent certificate generation via rcgen |
| (driver) | WDM driver | driver/ | 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
thiserrorfor library errors (analysiscrate)anyhowfor application errors (agent,server,installercrates)- 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