Windows Mini Filter Driver Deployment Guide

January 3, 2026 · View on GitHub

Overview

This guide covers deploying the agentsh Windows mini filter driver in production environments, including code signing requirements, installation procedures, and monitoring.

Requirements

Development/Testing

  • Windows 10/11 64-bit
  • Test signing mode enabled (bcdedit /set testsigning on)
  • Administrator privileges

Production

  • EV (Extended Validation) Code Signing Certificate
  • Microsoft Hardware Dev Center account (for attestation signing on Windows 10 1607+)
  • WHQL certification (optional, recommended for enterprise deployment)

Code Signing

Test Signing (Development)

  1. Create a test certificate:
makecert -r -pe -ss PrivateCertStore -n "CN=AgentSH Test" agentsh-test.cer
  1. Sign the driver:
signtool sign /v /s PrivateCertStore /n "AgentSH Test" /t http://timestamp.digicert.com agentsh.sys
  1. Enable test signing on target machine:
bcdedit /set testsigning on

Production Signing

  1. Obtain an EV Code Signing Certificate from a trusted CA (DigiCert, Sectigo, etc.)

  2. Sign the driver catalog:

inf2cat /driver:. /os:10_x64
signtool sign /v /ac cross-cert.cer /n "Your Company" /tr http://timestamp.digicert.com /td sha256 /fd sha256 agentsh.cat
  1. Submit for attestation signing (Windows 10 1607+):

Installation

Manual Installation

REM As Administrator
copy agentsh.sys %SystemRoot%\System32\drivers\
rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 132 agentsh.inf
fltmc load agentsh

Verify Installation

fltmc

Expected output:

Filter Name                     Num Instances    Altitude    Frame
------------------------------  -------------  ------------  -----
AgentSH                               3          385200       0

Uninstallation

fltmc unload agentsh
rundll32.exe setupapi.dll,InstallHinfSection DefaultUninstall 132 agentsh.inf
del %SystemRoot%\System32\drivers\agentsh.sys

Configuration

Fail Modes

ModeBehavior
FAIL_MODE_OPEN (default)Allow operations when policy service unavailable
FAIL_MODE_CLOSEDDeny operations when policy service unavailable

Configure via Go client:

client.SetConfig(&DriverConfig{
    FailMode:              FailModeClosed,
    PolicyQueryTimeoutMs:  5000,
    MaxConsecutiveFailures: 10,
})

Cache Tuning

ParameterDefaultRangeDescription
CacheMaxEntries4096100-100000Maximum cached decisions
CacheDefaultTTLMs5000100-3600000Default cache entry TTL

Monitoring

Registry Monitoring

The driver intercepts Windows registry operations via CmRegisterCallbackEx. This provides:

  • Operation interception: Create, set, delete, rename keys and values
  • Policy enforcement: Allow, deny, or require approval based on registry rules
  • High-risk path detection: Automatic detection of persistence and security-sensitive paths
  • MITRE ATT&CK mapping: Events include technique IDs for security monitoring

Registry Policy Configuration

In your policy file (agentsh.yaml):

registry_rules:
  # Allow application settings
  - name: allow-app-settings
    paths: ['HKCU\SOFTWARE\MyApp\*']
    operations: ["*"]
    decision: allow

  # Block persistence locations
  - name: block-run-keys
    paths:
      - 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*'
      - 'HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*'
    operations: [write, create, delete]
    decision: deny
    priority: 100
    notify: true

  # Require approval for service modifications
  - name: approve-service-changes
    paths: ['HKLM\SYSTEM\CurrentControlSet\Services\*']
    operations: [write, create, delete]
    decision: approve
    message: "Agent wants to modify service: {{.Path}}"
    timeout: 2m

Registry Operations

OperationDescription
readQuery key/value (QueryValue)
writeSet key/value (SetValue)
createCreate key (CreateKey)
deleteDelete key/value (DeleteKey, DeleteValue)
renameRename key (RenameKey)

High-Risk Registry Paths

The driver includes built-in detection for high-risk paths commonly used in attacks:

PathRiskMITRE Technique
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*CriticalT1547.001 - Registry Run Keys
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon*CriticalT1547.004 - Winlogon Helper DLL
HKLM\SYSTEM\CurrentControlSet\Services\*HighT1543.003 - Windows Service
HKLM\SOFTWARE\Policies\Microsoft\Windows Defender*CriticalT1562.001 - Disable Security Tools
HKLM\SYSTEM\CurrentControlSet\Control\Lsa*CriticalT1003 - Credential Dumping

Write operations to these paths are blocked by default even if default_action: allow is set.

Metrics

Retrieve via Go client:

metrics, _ := client.GetMetrics()
fmt.Printf("Cache hit rate: %.2f%%\n",
    float64(metrics.CacheHitCount) / float64(metrics.CacheHitCount + metrics.CacheMissCount) * 100)

Key metrics:

  • CacheHitCount / CacheMissCount - Cache efficiency
  • PolicyQueryTimeouts - Policy service responsiveness
  • FailOpenMode - Current fail mode state
  • AllowDecisions / DenyDecisions - Policy enforcement stats

Windows Event Log

Driver events appear in:

  • Event Viewer → Windows Logs → System
  • Source: AgentSH

Debug Output

In development, view DbgPrint output with DebugView (Sysinternals).

Troubleshooting

Driver won't load

  1. Check test signing: bcdedit | findstr testsigning
  2. Verify driver signature: signtool verify /v /pa agentsh.sys
  3. Check Event Viewer for errors

High latency

  1. Check metrics for cache hit rate (should be >80%)
  2. Verify policy service is running
  3. Consider increasing cache size

Fail-open triggered

  1. Check policy service connectivity
  2. Review ConsecutiveFailures metric
  3. Increase MaxConsecutiveFailures or fix connectivity

Security Considerations

  1. Production deployments must use EV-signed drivers
  2. Never disable Secure Boot in production
  3. Use FAIL_MODE_CLOSED for high-security environments
  4. Monitor fail mode transitions in SIEM
  5. Rotate session tokens regularly

WinFsp Coexistence

When using both the minifilter driver and WinFsp filesystem mounting, the agentsh process is automatically excluded from minifilter interception to prevent double-capture of file events.

How It Works

  1. Before mounting WinFsp, the Go client calls ExcludeSelf() on the driver client
  2. The driver stores the agentsh process ID in gExcludedProcessId
  3. All minifilter pre-callbacks (PreCreate, PreWrite, PreSetInfo) check for the excluded PID
  4. If the current process matches, the operation is allowed without policy check

Configuration

The exclusion is automatic when both systems are active. No additional configuration is required.

// This happens automatically in Filesystem.Mount()
if fs.driverClient != nil && fs.driverClient.Connected() {
    fs.driverClient.ExcludeSelf()
}

Troubleshooting

If you see duplicate file events:

  1. Verify the driver client is connected before mounting WinFsp
  2. Check that ExcludeSelf() completes without error
  3. Ensure the minifilter driver is running (version with MSG_EXCLUDE_PROCESS support)

To verify exclusion is working:

// Check metrics - file events should not double-count
metrics, _ := client.GetMetrics()
fmt.Printf("File queries: %d\n", metrics.FilePolicyQueries)

Sandbox Integration

The Windows sandbox uses two complementary isolation layers:

AppContainer (Primary)

  • Kernel-enforced capability isolation
  • Automatic registry isolation
  • Configurable network access
  • Full stdout/stderr capture from sandboxed processes
  • Automatic ACL cleanup on sandbox termination
  • Requires Windows 8+

Minifilter (Secondary)

  • Policy-based file/registry rules
  • Works with AppContainer for defense-in-depth
  • Can operate standalone for legacy systems

Configuration

config := platform.SandboxConfig{
    Name: "my-sandbox",
    WorkspacePath: "/path/to/workspace",
    AllowedPaths: []string{"/path/to/tools"},
    WindowsOptions: &platform.WindowsSandboxOptions{
        UseAppContainer: true,
        UseMinifilter: true,
        NetworkAccess: platform.NetworkOutbound,
        FailOnAppContainerError: true,
    },
}

sandbox, err := manager.Create(config)
if err != nil {
    log.Fatal(err)
}
defer sandbox.Close() // Automatically cleans up AppContainer profile and ACLs

// Execute command with full output capture
result, err := sandbox.Execute(ctx, "cmd.exe", "/c", "echo", "hello")
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Exit code: %d\n", result.ExitCode)
fmt.Printf("Stdout: %s\n", string(result.Stdout))
fmt.Printf("Stderr: %s\n", string(result.Stderr))

Network Access Levels

LevelDescription
NetworkNoneNo network access (default, maximum isolation)
NetworkOutboundInternet client connections only
NetworkLocalPrivate network access only
NetworkFullAll network access