Scanbridge
A unified, pluggable API for malware scanning in Rust.
Scanbridge provides an abstraction layer over multiple malware scanning engines, with built-in resilience patterns, policy enforcement, quarantine support, and compliance-ready audit logging.
Features
- Pluggable Architecture: Easily swap or combine scanning backends (ClamAV, VirusTotal, custom implementations)
- Circuit Breakers: Prevent cascading failures when backends become unhealthy
- Policy Engine: Configurable rules for handling scan results (block, quarantine, allow with warning)
- Quarantine Storage: Safely store and track infected files
- Audit Logging: Structured events via
tracingfor compliance environments - BLAKE3 Hashing: Fast deduplication with cryptographic security
- Runtime Agnostic: Works with any async runtime (designed for tokio)
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
= { = "1", = ["full"] }
Basic usage:
use *;
use MockScanner;
async
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ ScanManager │
│ Orchestrates scans, handles retries, manages multiple engines │
└────────────────────────────┬────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ CircuitBreaker │ │ CircuitBreaker │ │ CircuitBreaker │
│ (optional) │ │ (optional) │ │ (optional) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ ClamAV │ │ VirusTotal │ │ CustomScanner │
│ Backend │ │ Backend │ │ Backend │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Scan Outcomes
Every scan returns one of four outcomes:
| Outcome | Description |
|---|---|
Clean |
No threats detected |
Infected |
One or more threats found |
Suspicious |
Potentially harmful but not definitive |
Error |
Scan could not complete |
Circuit Breaker
The circuit breaker prevents cascading failures when a scanner becomes unhealthy:
use ;
use Duration;
let config = default
.with_failure_threshold // Open after 5 failures
.with_open_duration // Stay open 30s
.with_success_threshold; // Close after 3 successes
let protected = new;
States
- Closed: Normal operation, requests pass through
- Open: Backend failing, requests rejected immediately
- Half-Open: Probing with limited requests to check recovery
Fallback Behaviors
FailClosed: Reject scans when circuit is open (safest)FailOpen: Allow files through with warning (most available)Fallback(scanner): Use alternate scanner when primary fails
Policy Engine
Define rules for handling scan results:
use ;
let policy = new
.with_rule
.with_rule;
Quarantine
Safely store infected files:
use FilesystemQuarantine;
let quarantine = new?;
// Files are stored with integrity verification
// and can be retrieved, listed, or deleted
Audit Logging
All scan events are emitted via tracing at the scanbridge::audit target:
use FmtSpan;
// Configure a JSON subscriber for compliance logging
fmt
.json
.with_target
.init;
Events include:
scan_started/scan_completedpolicy_decisionquarantine_operation
Adding a Custom Backend
Implement the Scanner trait:
use *;
use async_trait;
See examples/custom_backend.rs for a complete example.
Feature Flags
| Feature | Description | Default |
|---|---|---|
tokio-runtime |
Tokio async runtime support | ✓ |
clamav |
ClamAV backend | ✗ |
virustotal |
VirusTotal API backend | ✗ |
Examples
# Basic scanning
# Circuit breaker demonstration
# Custom backend implementation
Error Handling
Scanbridge never panics. All errors are returned as typed ScanError variants:
EngineUnavailable: Scanner not respondingTimeout: Scan took too longConnectionFailed: Network/socket failureFileTooLarge: File exceeds size limitCircuitOpen: Circuit breaker is openRateLimited: API rate limit exceeded
All errors include context about which engine failed and why.
Performance
- BLAKE3 hashing: ~10x faster than SHA256
- Parallel scanning across multiple engines
- Stream processing for large files
- Connection pooling for network-based scanners
License
- MIT license (LICENSE-MIT)