Technical Deep-Dive: Architecture, Internals & Roadmap

Project Overview

AttributeValue
LanguageRust 2024 Edition (MSRV: 1.91+)
LicenseApache-2.0 (open core, hybrid commercial)
RepositoryEvilBit-Labs/DaemonEye
Open Issues43
Stars / Forks4 / 0
Async RuntimeTokio 1.49.0
Embedded Databaseredb 3.1.0
IPCProtobuf (prost 0.14.3) over interprocess 2.2.3
CLI Frameworkclap 4.6.0 (derive)
DaemonEye is a lightweight, privacy-respecting endpoint security monitoring system designed for offline-first and air-gapped environments. It provides cross-platform process visibility for operators who need detection capability without enterprise EDR overhead or cloud dependency. The three-component architecture cleanly separates privileged process collection from user-space detection and alerting, enforcing strict privilege separation at every boundary.

Codebase Metrics

MetricValue
Total Rust code~121,850 lines across 175 files
Integration test code~39,200 lines
Benchmark code~6,430 lines
Workspace crates6 (procmond, daemoneye-agent, daemoneye-cli, daemoneye-lib, collector-core, daemoneye-eventbus)
Protobuf schemas3 files (common.proto, ipc.proto, eventbus.proto)
CI workflows9 (audit, benchmarks, ci, codeql, copilot-setup, docs, release, scorecard, security)
Public structs~323
Public traits13
Public enums~95
Benchmark suites16 (Criterion-based)
Test functions~495 across 61 files

Crate Size Breakdown

CrateSLOCSource FilesRole
procmond23,25014Privileged process monitoring daemon
collector-core19,39822Extensible collector framework
daemoneye-eventbus14,57817Pub/sub event distribution and RPC
daemoneye-lib13,23120Shared library (models, storage, detection, IPC, crypto)
daemoneye-agent4,7068Detection orchestrator
daemoneye-cli781Operator command-line interface

Architecture Overview

Design Principles

Technology Stack

CategoryTechnologyVersion
LanguageRust 2024 EditionMSRV 1.91+
Async RuntimeTokio1.49.0
SerializationSerde, Postcard, Prost (protobuf)1.0.228 / 1.1.3 (no-default-features) / 0.14.3
Databaseredb (pure Rust embedded)3.1.0
CLIclap (derive)4.6.0
Process Enumerationsysinfo0.38.4
Detection Enginesqlparser0.60.0
IPC Transportinterprocess (Unix sockets / named pipes)2.2.3
Crypto (Hashing)BLAKE3, SHA21.8.3 / 0.10.9
Crypto (Merkle)rs-merkle1.5.0
Loggingtracing + tracing-subscriber0.1.44 / 0.3.23
Errorsthiserror / anyhow2.0.18 / 1.0.100
Task Runnerjust136 tasks
Testingcargo-nextest, insta, criterion-

Three-Component Security Architecture

DaemonEye implements strict privilege separation across three binaries with distinct security boundaries. Each component operates at a different privilege level with carefully controlled data access and network capabilities.

flowchart TD subgraph "Host System" P["procmond<br/>(elevated, drops after init)<br/>No network"] -->|"IPC protobuf<br/>CRC32 validated"| A["daemoneye-agent<br/>(user-space)<br/>Outbound-only"] A -->|"reads/writes"| DB1[("Event Store<br/>(redb)")] P -->|"writes"| DB2[("Audit Ledger<br/>(BLAKE3 chain)")] C["daemoneye-cli<br/>(minimal)<br/>No network"] -->|"reads"| DB1 & DB2 end A -->|"outbound alerts"| EXT[("Alert Sinks<br/>(webhook, syslog, file)")] A -.->|"mTLS (Enterprise)"| SC["Security Center"]

Component Privilege Matrix

ComponentPrivilegesNetworkDatabaseFunction
procmondElevated (drops after init)None (air-gapped)Write-only (audit ledger)Privileged process collector
daemoneye-agentMinimal (user-space)Outbound-onlyRead/write (event store)Detection orchestrator
daemoneye-cliMinimalNoneRead-onlyOperator CLI
daemoneye-libN/A (library)N/AN/AShared core
collector-coreN/A (framework)N/AN/ACollector framework
daemoneye-eventbusN/A (library)N/AN/AEvent bus infrastructure

Deployment Tiers

TierComponentsPricing
Free (Community)procmond + daemoneye-agent + daemoneye-cli (standalone)Free, unlimited hosts
Business (Professional)• Security Center + Enterprise integrations$199/site
Enterprise / Gov-IC• Kernel monitoring (eBPF) + Federated architecture + Advanced SIEMCustom

Data Flow Pipeline

The system follows a pipeline processing model where process data flows from collection through detection to alerting. Each stage enforces security boundaries and uses bounded channels for backpressure.

graph TD A["sysinfo<br/>(OS process table)"] --> B["SysinfoProcessCollector<br/>(ProcessCollector trait)"] B --> C["ProcessLifecycleTracker<br/>(start/stop/modify/suspicious)"] C --> D["WriteAheadLog<br/>(postcard + CRC32)"] D --> E["EventBusConnector<br/>(10MB buffer, backpressure)"] E -->|"IPC protobuf"| F["DaemoneyeBroker<br/>(pub/sub topics)"] F --> G["DetectionEngine<br/>(SQL AST validation)"] G --> H["AlertManager<br/>(dedup + rate limit)"] H --> I["AlertSink implementations<br/>(stdout, file, webhook, syslog)"] C --> J["AuditLedger<br/>(BLAKE3 hash chain)"] G --> K["Event Store<br/>(redb tables)"]

procmond: Privileged Process Collector

Overview

procmond is the privileged component responsible for process enumeration, lifecycle tracking, and audit trail maintenance. It runs with elevated privileges only during initialization, then drops to minimal permissions. It has zero network access and communicates solely via local IPC.

Execution Modes

procmond operates in two modes determined by the DAEMONEYE_BROKER_SOCKET environment variable:

Actor Mode (env var set — managed by daemoneye-agent):

Process Collection

The ProcessCollector trait provides cross-platform process enumeration:

pub trait ProcessCollector: Send + Sync {
    fn name(&self) -> &'static str;
    fn capabilities() -> ProcessCollectorCapabilities;
    async fn collect_processes() -> Result<(Vec<ProcessEvent>, CollectionStats)>;
    async fn collect_process(pid: u32) -> Result<ProcessEvent>;
    async fn health_check() -> Result<()>;
}

Platform implementations: linux_collector.rs, macos_collector.rs, windows_collector.rs

ProcessCollectionConfig defaults: enhanced_metadata=true, compute_hashes=false, max_processes=unlimited, skip_system=false, skip_kernel=false

Process Lifecycle Tracking

The lifecycle tracker (lifecycle.rs) detects four event types:

EventDetectionData
StartNew PID not in previous snapshotProcessSnapshot + detected_at
StopPID in previous but not current snapshotProcessSnapshot + runtime_duration
ModifiedPID exists but fields changedprevious + current + modified_fields list
SuspiciousAnomalous behavior patternsProcessSnapshot + reason + SuspiciousEventSeverity
ProcessSnapshot captures 14 fields: pid, ppid, name, executable_path, command_line, start_time, cpu_usage, memory_usage, executable_hash, user_id, accessible, file_exists, snapshot_time, and platform_metadata.

PID Reuse Handling: Compares start times to detect when a new process reuses a recycled PID.

Write-Ahead Log (WAL)

The WAL (wal.rs) provides crash recovery for event publishing:

Security Context

Platform-specific privilege detection:

Actor Model

In actor mode, ProcmondMonitorCollector communicates via an ActorHandle with a bounded mpsc channel (capacity: 100):

pub enum ActorMessage {
    HealthCheck { respond_to: oneshot::Sender<HealthCheckData> },
    UpdateConfig { config: Box<ProcmondMonitorConfig>, respond_to: oneshot::Sender<Result<()>> },
    GracefulShutdown { respond_to: oneshot::Sender<Result<()>> },
    BeginMonitoring,
    AdjustInterval { new_interval: Duration },
}

CollectorState transitions: WaitingForAgentRunningShuttingDownStopped


daemoneye-agent: Detection Orchestrator

Overview

The agent operates in user-space with minimal privileges. It manages the embedded event bus broker, coordinates collector lifecycles via RPC, executes SQL-based detection rules, and dispatches alerts through configured sinks.

Three-Phase Startup

Phase 1 — Initialization:

Agent State Machine

pub enum AgentState {
    Loading, // Spawning collectors, waiting for registration
    Ready, // All collectors registered and ready
    SteadyState, // Normal operation, monitoring broadcast
    StartupFailed { reason: String }, // Timeout or fatal error
    ShuttingDown, // Graceful shutdown in progress
}

Collector Registry

Thread-safe registry (RwLock<HashMap<String, CollectorRecord>>) managing collector lifecycles:

IPC Server

Listens for CLI connections via InterprocessServer. Receives DetectionTask messages and returns DetectionResult with process, network, filesystem, and performance event vectors.


daemoneye-lib: Shared Core Library

Module Architecture

Feature-gated module system for precise dependency control:

// Core modules (always available)
pub mod config;
pub mod crypto;
pub mod ipc;
pub mod models;
pub mod proto;
pub mod storage;
pub mod telemetry;

// Feature-gated modules
#[cfg(feature = "alerting")] pub mod alerting;
#[cfg(feature = "process-collection")] pub mod collection;
#[cfg(feature = "detection-engine")] pub mod detection;
#[cfg(feature = "kernel-monitoring")] pub mod kernel;
#[cfg(feature = "network-correlation")] pub mod network;

Models (models/)

Core data types shared across all components:

ProcessRecord: pid (u32), name (String), executable_path, command_line, start_time, cpu_usage (f64), memory_usage (u64), status, executable_hash (SHA-256), collection_time

Alert: id, severity (Info/Low/Medium/High/Critical), title, description, detection_rule_id, process (ProcessRecord), deduplication_key, timestamps

DetectionRule: id, name, description, sql_query, category, severity, enabled flag, validation constraints

SystemInfo: hostname, os_name, os_version, architecture, cpu_cores, total_memory, uptime, capabilities

Storage (storage.rs) — redb Integration

Five table definitions with JSON-serialized byte values:

TableKeyValueAccess Pattern
processesu64Vec<u8> (ProcessRecord)Agent R/W, CLI R/O
detection_rules&strVec<u8> (DetectionRule)Agent R/W
alertsu64Vec<u8> (Alert)Agent R/W, CLI R/O
system_infou64Vec<u8> (SystemInfo)Agent R/W
scan_metadatau64Vec<u8> (ScanMetadata)Agent R/W
DatabaseManager provides: new(), open(), CRUD operations per table, store_processes_batch(), cleanup_old_data(retention_days), get_stats(). Platform-agnostic directory validation with friendly error messages before database operations.

Note: redb Value trait implementations are pending (Task 8). Current implementation uses stub methods with proper transaction scaffolding.

Detection Engine (detection/)

SQL-based detection with AST validation for injection prevention:

Alert System (alerting.rs)

Trait-based multi-channel alert delivery:

#[async_trait]
pub trait AlertSink: Send + Sync {
    async fn send(&self, alert: &Alert) -> Result<DeliveryResult, AlertingError>;
    fn name(&self) -> &str;
    async fn health_check(&self) -> Result<(), AlertingError>;
}

Implementations: StdoutSink (JSON/Human/CSV), FileSink (append mode), with factory pattern (AlertSinkFactory) for config-driven creation.

AlertManager provides:

Cryptographic Subsystem (crypto.rs)

Certificate Transparency-style audit ledger:

Blake3Hasher: Computes BLAKE3 hashes (32 bytes / 64 hex chars) for data and string inputs.

AuditEntry (7 fields): sequence, timestamp, actor, action, payload_hash, previous_hash (chain link), entry_hash. Each entry's hash incorporates all fields plus the previous entry's hash, creating a tamper-evident chain.

AuditLedger: Append-only structure with add_entry(), verify_integrity() (validates both individual entry hashes and chain continuity), get_latest_hash(). Uses saturating_add for sequence numbers.

Planned: Merkle tree inclusion proofs via rs-merkle crate, Ed25519 signatures for external verification.

IPC Communication (ipc/)

Four-layer IPC architecture:

Configuration (config.rs)

Hierarchical configuration with precedence: CLI flags > environment variables (PROCMOND_*) > user config (~/.config/procmond/config.yaml) > system config (/etc/procmond/config.yaml) > embedded defaults.

Formats: YAML, JSON, TOML via figment.


Event Bus Architecture

daemoneye-eventbus Crate

Embedded pub/sub message broker providing multi-collector coordination:

Core Components (17 modules):

Topic Hierarchy

events.process.{start|stop|modify} → ProcessEvent with correlation metadata
control.health.heartbeat.{collector_id} → HeartbeatMetrics from procmond
control.collector.lifecycle → Registration/Deregistration requests
control.collector.{id}RPC control messages to collectors
control.rpc.response → RPC responses from collectors
events.collector.{id} → Event output from specific collector

Protobuf Message Definitions

Proto FileKey MessagesKey Enums
common.protoProcessFilter, HashCheck, HashResult, ProcessRecord, NetworkFilter, FilesystemFilter, PerformanceFilterTaskType (7 variants: ENUMERATE_PROCESSES, CHECK_PROCESS_HASH, MONITOR_PROCESS_TREE, etc.)
ipc.protoCollectionCapabilities, AdvancedCapabilities, DetectionTask, DetectionResult, CapabilityRequest/ResponseMonitoringDomain (PROCESS, NETWORK, FILESYSTEM, PERFORMANCE)
eventbus.protoAlertPayload, QoS settings, RPC request/responseMessageType (8), EventType (6), AlertSeverity (5), DeliveryGuarantee (3), DuplicateHandling

Quality of Service

The event bus supports configurable QoS:

Backpressure Management


Collector Framework (collector-core)

Overview

Extensible collection infrastructure (22 modules, 19,398 SLOC) providing shared operational foundation for multiple monitoring components.

Key Components

ModuleStructsPurpose
collector.rs3Core Collector trait and implementations
event_bus.rs19EventBus integration layer
high_performance_event_bus.rs6High-throughput variant for load testing
daemoneye_event_bus.rs7DaemonEye-specific EventBus bridge
rpc_services.rs5RPC service implementation
process_manager.rs2Collector process lifecycle management
task_distributor.rs3Task distribution across collectors
result_aggregator.rs5Multi-collector result combining
load_balancer.rs4Load balancing across collectors
capability_router.rs4Capability-based request routing
trigger.rs16 variantsEvent trigger definitions
analysis_chain.rs9Analysis pipeline stages
shutdown_coordinator.rs4Graceful shutdown orchestration
health_monitor.rs2Health check infrastructure
performance.rs10Performance metrics collection

Key Traits


Security Model

Defense in Depth

LayerMechanismImplementation
Memory SafetyRust ownership + unsafe_code = "forbid"Workspace-level lint, zero unsafe code policy
Integer SafetyOverflow checks in release buildsoverflow-checks = true in [profile.release]
Privilege SeparationThree-component isolationOnly procmond runs elevated, immediate drop after init
Network IsolationZero inbound, outbound-only for agentprocmond has no network access whatsoever
SQL Injection PreventionAST validation with sqlparserWhitelist-based function approval, SELECT-only
IPC IntegrityCRC32C validation on all messagesProtobuf framing with integrity checks
Audit TrailBLAKE3 hash chainCertificate Transparency-style tamper-evident ledger
Data SanitizationSensitive field redactionCommand lines, env vars, file paths sanitized before logging
Concurrency SafetyTokio primitives, no lock-while-awaitclippy::await_holding_lock = "deny"

Cryptographic Standards

PurposeAlgorithmCrate
Audit hashingBLAKE3blake3 1.8.3
Executable hashingSHA-256sha2 0.10.9
Merkle proofsBLAKE3-based Merkle treers-merkle 1.5.0
Signatures (planned)Ed25519ed25519-dalek
AEAD (Enterprise)ChaCha20-Poly1305, AES-GCMchacha20poly1305, aes-gcm
KDF (Enterprise)HKDF-SHA256, Argon2id-
TLS (Enterprise)TLS 1.2+ min, 1.3 preferredrustls

Performance Budgets & Benchmarking

Performance Targets

MetricTarget
CPU Usage< 5% sustained during continuous monitoring
Memory< 100 MB resident under normal operation
Process Enumeration< 5 seconds for 10,000+ processes
Database Writes> 1,000 records/sec
Alert Latency< 100ms per detection rule
Query ResponseSub-second for 100k+ events/min

Benchmark Suite (16 Criterion Suites)

CrateSuiteFocus
procmondprocess_collector_benchmarksProcess enumeration performance
procmondwal_benchmarksWrite-Ahead Log throughput
procmondeventbus_benchmarksEvent bus throughput from collector
procmondserialization_benchmarksPostcard serialization speed
procmondsystem_benchmarksSystem-level monitoring overhead
daemoneye-libprocess_collectionCore collection performance
daemoneye-libdatabase_operationsredb read/write patterns
daemoneye-libdetection_engineSQL detection rule execution
daemoneye-libipc_communicationIPC latency and throughput
daemoneye-libipc_performance_comprehensiveExtended IPC analysis
daemoneye-libipc_client_validation_benchmarksClient validation overhead
daemoneye-libalert_processingAlert delivery pipeline
daemoneye-libcryptographic_operationsBLAKE3/SHA2 hashing speed
daemoneye-eventbusthroughputEvent delivery rate
daemoneye-eventbusipc_performanceIPC transport benchmarks
collector-corecollector_benchmarksCollector framework performance

Resource Management


CI/CD Pipeline

GitHub Actions Workflows

WorkflowFilePurpose
CIci.ymlQuality (rustfmt + clippy strict), test (nextest + release build), cross-platform matrix, coverage (LCOV + Codecov)
Benchmarksbenchmarks.ymlCriterion benchmarks with baseline caching, 20% regression threshold, manual dispatch with suite selection
Auditaudit.ymlDependency vulnerability scanning
CodeQLcodeql.ymlStatic analysis and security scanning
Securitysecurity.ymlSecurity-focused checks
Scorecardscorecard.ymlOSSF Scorecard security assessment
Releaserelease.ymlMulti-platform release builds
Docsdocs.ymlDocumentation generation
Copilot Setupcopilot-setup-steps.ymlGitHub Copilot workspace configuration

CI Test Matrix

Development Commands (justfile — 136 tasks)

CategoryKey Commands
Corejust fmt, just lint, just build, just test, just check
Benchmarksjust bench, just bench-procmond, just bench-database, just bench-detection, just bench-ipc, just bench-crypto
Securityjust audit-deps, just deny-deps, just security-scan
Distributionjust goreleaser-build, just goreleaser-snapshot, platform-specific test targets
Releasejust release, just release-patch, just release-minor, just release-major

Error Handling Architecture

Two-tier error handling strategy:

Key Error Types

Error TypeModuleVariants
ProcessCollectionErrorprocmond6 (SystemEnumerationFailed, ProcessAccessDenied, ProcessNotFound, InvalidProcessData, PlatformError, CollectionTimeout)
AlertingErrordaemoneye-lib11 (SinkError, ConfigurationError, Timeout, SerializationError, IoError, FileSinkError, StdoutSinkError, RateLimitExceeded, DeduplicationError, HealthCheckFailed, UnknownSinkType)
StorageErrordaemoneye-lib10 (MissingDirectory, NotADirectory, DirectoryPermissionDenied, DatabaseCreationFailed, DatabaseError, StorageError, TableError, TransactionError, CommitError, SerializationError, IoError, TableNotFound, RecordNotFound)
CryptoErrordaemoneye-lib3 (Hash, Signature, Key)
WalErrorprocmond6 (Io, Serialization, Corruption, InvalidSequence, FileRotation, Replay)
EventBusConnectorErrorprocmond8 (Wal, EventBus, Connection, BufferOverflow, EnvNotSet, Serialization, PayloadTooLarge, MaxRetriesExceeded)
RegistrationErrorprocmond7 (RegistrationFailed, RegistrationRejected, Timeout, HeartbeatFailed, DeregistrationFailed, EventBusError, InvalidStateTransition)
RegistryErrordaemoneye-agent3 (AlreadyRegistered, NotFound, InvalidHeartbeatInterval)
CollectorConfigErrordaemoneye-agent6 (FileNotFound, IoError, ParseError, ValidationError, BinaryNotFound, DuplicateCollectorId)

Platform Support

OSVersionArchStatus
LinuxUbuntu 20.04+ LTS, RHEL/CentOS 8+, Debian 11+x86_64, ARM64Primary
macOS14.0+ (Sonoma)x86_64, ARM64Primary
Windows10+, Server 2019+x86_64, ARM64Primary
LinuxAlpine 3.16+, Amazon Linux 2+x86_64, ARM64Secondary
FreeBSD13.0+x86_64, ARM64Secondary
Platform-Specific Dependencies:

Internal Dependency Graph

graph TD PROCMOND["procmond<br/>(23,250 SLOC)"] --> COLLECTOR_CORE["collector-core<br/>(19,398 SLOC)"] PROCMOND --> EVENTBUS["daemoneye-eventbus<br/>(14,578 SLOC)"] PROCMOND --> LIB["daemoneye-lib<br/>(13,231 SLOC)"] AGENT["daemoneye-agent<br/>(4,706 SLOC)"] --> LIB AGENT --> EVENTBUS AGENT --> COLLECTOR_CORE CLI["daemoneye-cli<br/>(78 SLOC)"] --> LIB

Testing Strategy

Three-Tier Architecture

TierScopeToolsVolume
UnitIndividual functions, structs, trait implstokio-test, trait mocking, inline #[cfg(test)] modules~495 test functions across 61 files
IntegrationCross-component, database operationsinsta (snapshots), predicates, real redb instances, tempfile~39,200 lines in dedicated test files
PerformanceRegression detectionCriterion (16 benchmark suites), 20% CI threshold~6,430 lines of benchmark code

Quality Enforcement


Known Technical Debt & Implementation Status

ItemStatusTracking
redb Value trait implementations for typed table accessPending (Task 8)Stub methods with proper transaction scaffolding in place
Merkle tree inclusion proofs via rs-merklePlannedPlaceholder in AuditLedger::generate_inclusion_proof()
Windows privilege detectionUnimplementedIssue #149 — currently returns degraded mode
daemoneye-cli full implementationMinimal (78 SLOC)Basic config load + DB stats query only
Kernel monitoring (eBPF)Feature-gated stubEnterprise tier — kernel.rs module
Network correlationFeature-gated stubEnterprise tier — network.rs module
Webhook and syslog AlertSink implementationsPlannedFactory pattern ready, only stdout and file implemented
Ed25519 signature support for audit entriesPlannedDependency declared, not yet integrated

Configuration Parameters Reference

ParameterTypeDefaultComponent
DAEMONEYE_BROKER_SOCKETenv var(unset)procmond — toggles actor vs standalone mode
scan_interval_msu64(from config)agent — RPC polling interval
startup_timeoutu6460sagent — wait for collectors
heartbeat_interval_secsu6430all — periodic health signal
max_buffer_sizeusize10MBprocmond — WAL backpressure trigger
max_queue_sizeusize1000eventbus — per-client queue depth
ACTOR_CHANNEL_CAPACITYusize100procmond — actor mailbox size
max_concurrent_requestsusize10procmond — parallel RPC handler limit
default_timeoutDuration30sRPC — operation timeout
dedup_window_secondsu64300 (5 min)alerting — deduplication window

Developer Gotchas


Document Metadata

FieldValue
Document Version1.0
Created Date2026-03-08
Generated FromCodebase analysis (121,850 SLOC), AGENTS.md, Dosu knowledge base, GitHub API
Approval StatusDraft