How to Build Your First Windows Defender Application Control (WDAC) Policy

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
WDAC is the Windows application control feature that actually blocks code at the kernel level: before it can run, before it can inject into other processes, before it can establish C2 communications. Most malware, including LOLBin abuse and fileless attacks, can be blocked by a well-configured WDAC policy.
The challenge is deployment: a WDAC policy that blocks too aggressively breaks legitimate applications. The audit-mode-first workflow prevents this by capturing everything that legitimately runs in your environment before enforcing any blocks.
WDAC vs. AppLocker: Which to Use
Both WDAC and AppLocker are Microsoft application control technologies. Defenders frequently ask which to use:
| Feature | WDAC | AppLocker |
|---|---|---|
| Enforcement level | Kernel (before execution) | User process (process launch) |
| Bypass difficulty | Significantly harder | More easily bypassed |
| OS availability | Windows 10/11, Server 2016+ | Windows 7+, Server 2008+ |
| Deployment | Intune, Group Policy, MDM | Group Policy |
| Policy format | XML, deployed as binary | XML via Group Policy |
| Managed installer support | Yes | No |
| Driver control | Yes (kernel drivers) | No |
| Script control | Yes (PowerShell constrained language mode) | Limited |
Microsoft's recommendation: Use WDAC where possible; AppLocker is supplementary for systems where WDAC cannot be deployed. They can run simultaneously.
When to use WDAC: Modern Windows 10/11 or Server 2016+ environments where you can invest in proper policy management. WDAC provides significantly better security but requires more upfront investment.
When to use AppLocker: Legacy environments (pre-Windows 10), when you need a quick partial control while building toward WDAC, or for user-mode script control on systems that cannot fully enforce WDAC.
Step 1: Create a Base Policy in Audit Mode
Option 1: WDAC Wizard (Microsoft's GUI tool)
Download from: https://webapp-wdac-wizard.azurewebsites.net/
- Provides a guided policy creation workflow
- Generates signed or unsigned XML policies
- Supports policy supplements and merging
Option 2: PowerShell: create a baseline policy from Microsoft's recommended templates:
# Requires: Windows 10/11 or Server 2016+, ConfigCI module (built-in)
# Start with Microsoft's default Windows mode template
# This allows Windows components, WHQL-signed drivers, and Windows Store apps
$PolicyPath = "C:\WDAC\BasePolicy.xml"
# Get the path to the default policy templates
$TemplatePath = "C:\Windows\schemas\CodeIntegrity\ExamplePolicies"
Get-ChildItem $TemplatePath # Lists available templates
# Use the DefaultWindows template as a starting point
Copy-Item "$TemplatePath\DefaultWindows_Audit.xml" $PolicyPath
# Set the policy to Audit mode (0 = audit, 1 = enforce)
Set-RuleOption -FilePath $PolicyPath -Option 3 # Audit mode
# Enable script enforcement (blocks unsigned PowerShell scripts)
Set-RuleOption -FilePath $PolicyPath -Option 11 # Disabled:Script Enforcement (remove this option to enforce)
# Remove Audit Mode for enforcement later: but don't do this yet
# Set-RuleOption -FilePath $PolicyPath -Option 3 -Delete
# Set the policy ID and name
[xml]$policyXml = Get-Content $PolicyPath
$policyXml.SiPolicy.PolicyID = "{$(New-Guid)}"
$policyXml.SiPolicy.FriendlyName = "Corporate WDAC Policy v1"
$policyXml.Save($PolicyPath)
# Convert XML to binary format for deployment
ConvertFrom-CIPolicy -XmlFilePath $PolicyPath -BinaryFilePath "C:\WDAC\BasePolicy.p7b"
# Deploy to the local machine for testing
Copy-Item "C:\WDAC\BasePolicy.p7b" \
"$env:windir\System32\CodeIntegrity\CIPolicies\Active\{policy-guid-here}.cip"
# Restart required for policy to take effect
# Restart-Computer (do this when ready)
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
Step 2: Capture Audit Events and Build Trust Rules
Run in audit mode for 1-2 weeks to capture all code that legitimately runs:
# Query Code Integrity audit events (Event ID 3076)
# These are files that WOULD be blocked in enforcement mode
Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' |
Where-Object Id -eq 3076 |
ForEach-Object {
$xml = [xml]$_.ToXml()
[PSCustomObject]@{
TimeCreated = $_.TimeCreated
FileName = $xml.Event.EventData.Data | Where-Object Name -eq 'File Name' | Select-Object -ExpandProperty '#text'
SHA256 = $xml.Event.EventData.Data | Where-Object Name -eq 'SHA256 Flat Hash' | Select-Object -ExpandProperty '#text'
PolicyName = $xml.Event.EventData.Data | Where-Object Name -eq 'Policy Name' | Select-Object -ExpandProperty '#text'
}
} | Export-Csv "C:\WDAC\audit-events.csv" -NoTypeInformation
# Review the blocked applications list
Import-Csv "C:\WDAC\audit-events.csv" |
Sort-Object FileName -Unique |
Select-Object FileName, SHA256 |
Format-Table -AutoSize
Create trust rules for legitimate software found in audit events:
# Option 1: Publisher rule (preferred: survives software updates)
# Extract signing certificate info from a file
$cert = (Get-AuthenticodeSignature -FilePath "C:\Program Files\SomeApp\app.exe").SignerCertificate
if ($cert) {
# Create a publisher rule
$rule = New-CIPolicyRule \
-Level Publisher \
-FilePath "C:\Program Files\SomeApp\app.exe"
Add-CIPolicyRules -Policy $PolicyPath -Rules $rule
}
# Option 2: Generate rules from a reference machine
# (Best practice: run on a clean, fully configured machine)
New-CIPolicy \
-Level Publisher \
-Fallback Hash \
-FilePath "C:\WDAC\ApplicationPolicy.xml" \
-ScanPath "C:\Program Files" \
-UserPEs # Include user-mode executables
# Option 3: Generate rules from audit events directly
New-CIPolicy \
-Level Publisher \
-Fallback Hash \
-FilePath "C:\WDAC\AuditDerivedPolicy.xml" \
-Audit # Scan audit event log to build policy from observed applications
# Merge application policy with base policy
Merge-CIPolicy \
-PolicyPaths $PolicyPath, "C:\WDAC\ApplicationPolicy.xml" \
-OutputFilePath "C:\WDAC\MergedPolicy.xml"
Step 3: Add the Microsoft Recommended Block Rules
Microsoft maintains a list of known vulnerable drivers and LOLBins that WDAC should block: attackers abuse these to bypass application control. Include these in every WDAC policy.
# Download the recommended block list from Microsoft
# https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/design/applications-that-can-bypass-wdac
# Save the XML as BlockList.xml
# Merge block rules into your policy
Merge-CIPolicy \
-PolicyPaths "C:\WDAC\MergedPolicy.xml", "C:\WDAC\BlockList.xml" \
-OutputFilePath "C:\WDAC\FinalPolicy.xml"
# The block list denies execution of:
# mshta.exe, wscript.exe, cscript.exe when used for policy bypass
# Known vulnerable signed drivers (LoLDrivers)
# Tools like PsExec, BGInfo, wmic used in specific bypass scenarios
# See: https://loldrivers.io/ for the full vulnerable driver list
Step 4: Switch to enforcement mode:
# Remove the Audit Mode option to enforce the policy
Set-RuleOption -FilePath "C:\WDAC\FinalPolicy.xml" -Option 3 -Delete
# Convert to binary
$policyGuid = ([xml](Get-Content "C:\WDAC\FinalPolicy.xml")).SiPolicy.PolicyID.Trim('{}')
ConvertFrom-CIPolicy \
-XmlFilePath "C:\WDAC\FinalPolicy.xml" \
-BinaryFilePath "C:\WDAC\{$policyGuid}.cip"
# Deploy via Intune (preferred for enterprise):
# Intune > Devices > Configuration Profiles > Create >
# Endpoint protection > Windows Defender Application Control
# Upload the .cip file as Custom OMA-URI:
# OMA-URI: ./Vendor/MSFT/ApplicationControl/Policies/{PolicyGUID}/Policy
# Data type: Base64
# Value: (base64-encode the .cip file)
# Or deploy via Group Policy:
Copy-Item "C:\WDAC\{$policyGuid}.cip" \
"\\fileserver\Netlogon\WDAC\{$policyGuid}.cip"
# GPO: Computer Configuration > Windows Settings > Security Settings >
# Application Control Policies > Windows Defender Application Control
The bottom line
WDAC provides kernel-level code integrity enforcement that blocks unauthorized execution before it happens: more effective than AppLocker and significantly harder to bypass. Build a base policy from Microsoft's DefaultWindows template, deploy in audit mode for 1-2 weeks, review Event ID 3076 to identify legitimate software that would be blocked, create publisher rules for trusted applications, merge in Microsoft's recommended block list, then switch to enforcement mode. Deploy via Intune for enterprise scale or Group Policy for domain-joined environments.
Frequently asked questions
What is Windows Defender Application Control (WDAC)?
WDAC is a Windows kernel-level code integrity feature that prevents unauthorized code from executing: blocking unsigned binaries, untrusted drivers, and explicitly denied applications before they can run. Unlike AppLocker (which operates at process launch), WDAC enforcement happens in the kernel before code is loaded into memory, making it significantly harder to bypass. Policies are defined in XML, specify trust via publisher certificates or file hashes, and are deployed via Intune or Group Policy.
How do you deploy a WDAC policy without breaking applications?
Deploy in audit mode first (Option 3 in the policy XML). Audit mode logs what would be blocked (Event ID 3076 in Microsoft-Windows-CodeIntegrity/Operational) without actually blocking anything. Run for 1-2 weeks to capture all legitimate software. Review the audit events, create publisher or hash rules for each legitimate application, merge into the base policy, then remove the audit option to enforce. Never skip audit mode in production environments.
What is the difference between WDAC and AppLocker?
Both are Windows application control technologies but differ in architecture and enforcement level. AppLocker operates in user mode and enforces rules based on executable path, publisher, or file hash. It can be bypassed by kernel drivers and does not protect the boot process. WDAC (Windows Defender Application Control) enforces code integrity at the kernel level via the hypervisor (when VBS is enabled): it cannot be bypassed by user-mode code or standard admin privileges. WDAC is the Microsoft-recommended replacement for AppLocker in Windows 10/11 and Server 2016+. AppLocker is easier to deploy and manage; WDAC provides stronger security guarantees. Microsoft recommends using WDAC first, then AppLocker for user-mode supplemental rules if needed.
What is the WDAC Wizard and how does it simplify policy creation?
The WDAC Policy Wizard is a free Microsoft GUI tool that simplifies creating WDAC policies without hand-editing XML. It guides you through: selecting a base policy template (allow Microsoft mode, Windows works-only, or default Windows mode), adding publisher rules, adding path rules, and running a system scan to capture all currently running software as allowed rules. Download from Microsoft's GitHub. For deployment at scale, use the Microsoft Endpoint Configuration Manager (MECM/SCCM) WDAC integration or Microsoft Intune's Endpoint Security > Application Control policy to push WDAC policies to managed devices without Group Policy.
How do I write a WDAC rule to allow a specific application?
WDAC rules have three types: Publisher rules (most preferred — allow all files signed by a specific publisher, optionally scoped to a product name or version range), Hash rules (allow a specific file by its SHA256 hash — breaks when the file is updated), and Path rules (allow all files in a specific directory — weakest, can be exploited if the path is writable). For trusted commercial software (Adobe, Google, Microsoft), use Publisher rules: they automatically cover updates without rule changes. Use the Get-AppLockerFileInformation or New-CIPolicy PowerShell cmdlets to generate rules from existing files. Hash rules are appropriate for in-house applications that do not have Authenticode signatures.
How do I handle a software deployment that breaks after WDAC enforcement is turned on?
When a deployment fails after WDAC enforcement activates, the first step is checking Event ID 3077 in the Microsoft-Windows-CodeIntegrity/Operational log on the affected machine -- this records each blocked execution with the file name, hash, and policy name that blocked it. For a rapid unblock without disabling enforcement, add a hash rule for the specific blocked binary: run 'Get-FileHash <path> -Algorithm SHA256' and create a supplemental policy with a hash-based allow rule using New-CIPolicyRule -Level Hash -FilePath <path>, then merge it with your base policy and redeploy. For recurring issues with a vendor application, contact the vendor to obtain Authenticode-signed binaries -- most enterprise software vendors sign their installers; if they do not, escalate it as a security concern. For in-house tools, implement a code-signing workflow using your internal PKI and add the signing certificate as a publisher rule. Avoid the temptation to add path-based allow rules for writable directories such as temp folders -- attackers routinely exploit path rules by dropping malicious binaries into allowed paths.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
