docs(§1.6): Add threat model documentation to BEST-PRACTICES.md

§1.6 — Threat Model & Hardening Trade-offs: New section in BEST-PRACTICES.md §2.1
explains why Defender/Firewall/UAC are disabled in the template VM:
- Current state: tradeoff table (AV overhead vs attack surface, firewall fragility, UAC blocking elevated WinRM)
- Acceptable conditions: isolated lab, trusted code, no host sharing, VMnet8 not exposed
- Breaking conditions: untrusted code builds, shared host, LAN-exposed network
- Mitigations: how to re-enable each feature with specific cost/benefit trade-offs

Addresses security documentation gap — future modifications to security posture
can now reference this single authoritative source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Simone
2026-05-10 20:18:18 +02:00
parent f46e4a8ca3
commit a0c94cb3d3
2 changed files with 126 additions and 49 deletions
+95
View File
@@ -53,6 +53,101 @@ $session = New-PSSession -ComputerName $ip -Port 5986 -UseSSL -Authentication Ba
---
## 2.1. Threat Model — Disabled Security Features
### Current state: Defender, Firewall, and UAC disabled
The template VM disables Windows Defender, Windows Firewall, and User Account Control (UAC).
This is **intentional** — not a bug, not an oversight. Each has tradeoffs:
| Feature | Disabled? | Why | Cost if enabled |
|---------|-----------|-----|-----------------|
| **Windows Defender** | Yes | Real-time AV scanning blocks .NET compilation, Python wheels, and npm installs | 510 min per build overhead; false positives on dev tools |
| **Windows Firewall** | Yes | Blocks inbound WinRM even with rules; requires Domain/Home profile tuning | Complex rules; fragile across OS updates |
| **UAC (LocalAccountTokenFilterPolicy)** | Yes | Prevents non-elevated WinRM scripts from running builds | Requires built-in Administrator account; WinRM behaves like a user with limited rights |
### When this threat model is acceptable
Current threat model is **safe** if **ALL** of these are true:
1. **Isolated lab environment** — Build VMs exist only on VMnet8 (NAT), not on host LAN.
2. **No shared resources** — Host is not shared with untrusted users or concurrent CI systems.
3. **Trusted source code** — Code being built is from trusted repositories (internal team only).
4. **No external access** — VMnet8 is not bridged or exposed to corporate LAN or internet.
5. **Act_runner is trusted** — The act_runner service token cannot be used to access host resources outside the isolated network.
If all conditions hold, the attack surface is limited to:
- Network eavesdropping on 192.168.79.0/24 (mitigated: WinRM is HTTPS)
- Code injection via malicious commits (mitigated: code review process)
- Privilege escalation from VM to host (mitigated: VMs are ephemeral; no persistence)
### When the model breaks down
**Do NOT use this configuration if:**
- ❌ **Third-party code builds** — Running untrusted vendor code (open-source projects, third-party libraries with build scripts)
- ❌ **Shared build machine** — Other teams or processes share the host CPU/storage
- ❌ **LAN-exposed network** — VMnet8 is bridged to corporate LAN or internet
- ❌ **Host resource sharing** — Build VMs can access host shares, USB drives, or external storage
- ❌ **Long-lived VMs** — VMs are not destroyed after each build (antivirus blind spot for persistence)
In these scenarios, disabled AV and firewall create **unacceptable risk**.
### Mitigations if constraints change
If you must run in a less-isolated environment, re-enable protections **with cost awareness**:
#### Option 1: Re-enable Firewall only (lowest cost)
```powershell
# In template VM via WinRM, before taking BaseClean snapshot:
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled $true
# Add inbound rule for WinRM listener
New-NetFirewallRule -Name "WinRM-HTTPS" `
-DisplayName "Windows Remote Management (HTTPS)" `
-Direction Inbound `
-LocalPort 5986 `
-Protocol TCP `
-Action Allow
```
**Cost:** 3060 seconds per build (firewall rule evaluation + logging).
**Benefit:** Blocks outbound malware callbacks if VM is compromised.
#### Option 2: Re-enable Defender with exclusions (moderate cost)
```powershell
# In template VM, enable Defender but exclude build directories:
Enable-MpComputerDefault # Re-enable Defender
Add-MpPreference -ExclusionPath @(
'C:\Build',
'C:\Users\ci_build\AppData\Local\Microsoft\dotnet',
'C:\Users\ci_build\AppData\Roaming\npm'
) -Force
# Reduce scanning aggressiveness:
Set-MpPreference -DisableRealtimeMonitoring $false -DisableBehaviorMonitoring $true
```
**Cost:** 25 min per build (initial scan; exclusions help but don't eliminate overhead).
**Benefit:** Detects known malware uploaded in build artifacts.
#### Option 3: Enable UAC for elevated builds only (requires refactor)
```powershell
# NOT RECOMMENDED without major refactoring.
# WinRM remote commands run as non-elevated user; builds fail.
# Requires either:
# - Running WinRM as built-in Administrator (security anti-pattern)
# - Adding explicit runas prompts (breaks automation)
# - Using Windows Task Scheduler instead of WinRM (complexity)
```
### Audit and sign-off
Before deploying to production or a shared host:
1. **Document the decision:** Update this section with current date and approver name.
2. **Test the mitigations:** Create test clone, enable firewall/AV, measure build time overhead.
3. **Establish monitoring:** Run Watch-RunnerHealth.ps1 continuously; alert on service restarts.
4. **Plan rotation:** Schedule quarterly credential rotation (see §1 Credential Management).
---
## 3. act_runner Service Stability
### Windows Service Recovery Policy