Policy Engine Module
The Policy Engine receives classification verdicts from the ML Classifier and executes enforcement actions. Currently it logs verdicts to the console; the architecture supports extending it with quarantine, alerting, and blocking capabilities.
Related: ML Classifier Module Β· Scanner Module Β· Scan Pipeline Flow Β· Adding Detection Rules
1. Source Files
| File | Purpose |
|---|---|
scanner/policy.cpp |
ApplyPolicy() implementation |
scanner/policy.h |
ApplyPolicy() declaration |
2. Pipeline Position
flowchart LR
ML["Classify()\nβ SCAN_RESULT"]
POL["ApplyPolicy(\n path,\n verdict)"]
subgraph Actions["Current Actions"]
Log["Console Output"]
end
subgraph Future["Future Actions"]
Quarantine["Quarantine File"]
Alert["Send Alert"]
Block["Block Execution"]
end
ML --> POL
POL --> Log
POL -.-> Quarantine
POL -.-> Alert
POL -.-> Block
style POL fill:#e07a5f,color:#fff
style Actions fill:#2d6a4f,color:#fff
style Future fill:#6c757d,color:#fff
3. Current Implementation
flowchart TD
Input["ApplyPolicy(path, verdict)"]
Input --> Switch{"verdict?"}
Switch -->|SCAN_MALICIOUS| PrintMal["wprintf('[MALICIOUS] %s')"]
Switch -->|SCAN_CLEAN| PrintClean["wprintf('[CLEAN] %s')"]
Switch -->|default| NoOp["No action"]
style PrintMal fill:#e63946,color:#fff
style PrintClean fill:#2d6a4f,color:#fff
style NoOp fill:#6c757d,color:#fff
Function Signature
void ApplyPolicy(const wchar_t* path, SCAN_RESULT verdict);
| Parameter | Type | Description |
|---|---|---|
path |
const wchar_t* |
Full Win32 file path of the scanned file |
verdict |
SCAN_RESULT |
Classification result from Classify() |
Current Actions
| Verdict | Action | Output Format |
|---|---|---|
SCAN_MALICIOUS |
Console print | [MALICIOUS] C:\path\to\file.exe |
SCAN_CLEAN |
Console print | [CLEAN] C:\path\to\file.exe |
SCAN_SUSPICIOUS |
No action | β |
SCAN_ERROR |
No action | β |
4. Extension Architecture
The policy engine is the natural extension point for adding response actions. The current switch statement can be extended with any of the following patterns:
flowchart TB
subgraph PolicyActions["Potential Policy Actions"]
direction TB
subgraph Logging["Tier 1: Logging"]
Console["Console Output β
(current)"]
FileLog["File Logging"]
EventLog["Windows Event Log"]
end
subgraph Response["Tier 2: Response"]
Quarantine["Move to Quarantine\nFolder"]
Rename["Rename with\n.quarantine extension"]
Restrict["Set restrictive\nACLs"]
end
subgraph Active["Tier 3: Active Defense"]
Kill["Terminate Process\n(using PID)"]
Block["Prevent Execution\n(driver callback)"]
Network["Network Alert\n(SIEM integration)"]
end
end
style Logging fill:#2d6a4f,color:#fff
style Response fill:#e07a5f,color:#fff
style Active fill:#e63946,color:#fff
Adding a New Policy Action
See Adding Detection Rules for the complete guide. The minimal change is:
- Add a new case to the
switchinApplyPolicy() - Implement the action function
- Optionally add new
SCAN_RESULTvalues to thescanner_api.henum
5. Design Considerations
| Aspect | Current | Recommended for Production |
|---|---|---|
| Logging | Console only | File log + Windows Event Log |
| Quarantine | Not implemented | Move file + record original path |
| Alerting | Not implemented | Named pipe / socket to SIEM |
| Blocking | Not implemented | Requires driver-level callback to return FLT_PREOP_COMPLETE |
| Audit trail | Not implemented | SQLite or structured log file |
Important: Active blocking (preventing file execution) requires changes to the kernel driver. The current driver is observe-only β all pre-operation callbacks return FLT_PREOP_SUCCESS_*, never FLT_PREOP_COMPLETE with STATUS_ACCESS_DENIED. Implementing blocking would require:
- Adding a reply mechanism to
FltSendMessage(enable reply buffer) - Having the scanner send a BLOCK/ALLOW verdict back through the port
- The driverβs pre-op callback waiting for the reply before returning
Next Steps
- Add new detection rules: Adding Detection Rules
- Understand the classification input: ML Classifier Module
- Full scan pipeline context: Scan Pipeline Flow