Most endpoints still run any code a user or an attacker can get onto the disk, and rely on antivirus to spot the bad ones. Application allowlisting reverses that default: code runs only if a policy says it may. This guide covers how allowlisting works on Windows with App Control for Business (formerly Windows Defender Application Control, WDAC) and AppLocker, where Smart App Control and ringfencing fit, which rule types to use, and how to roll out from audit mode to enforcement without breaking the business. It is written for endpoint engineers and security architects, and also notes the Linux equivalent, fapolicyd.
Key takeaways
- Deny by default is the point. Allowlisting turns "run unless known bad" into "run only if approved", which stops unknown malware, unapproved tools and many living-off-the-land chains that antivirus misses.
- Use App Control for Business as the enforcement layer on Windows. Microsoft services it as a security feature; AppLocker is defence in depth only and receives no new features, so keep it for per-user rules and older systems.
- Rule type decides how strong the policy really is. Signer and hash rules are robust; path rules on folders a standard user can write to are a hole, and broad publisher rules quietly trust every binary a vendor ever signed.
- Remove local admin rights before or with enforcement. Administrators, and malware running as one, can get around managed installer trust and tamper with unsigned policies.
- Audit mode is a phase, not a destination. Run it with a fixed end date, build rules from events 3076 and 8028, enforce in rings, and keep a tested rollback.
What application allowlisting controls
NIST SP 800-167 defines an application allowlist as "a list of applications and application components that are authorized for use in an organization", enforced by technology that controls which applications may execute on a host. Microsoft describes the shift plainly: application control "changes Windows from a place where all code runs unless your AV solution confidently predicts it's bad, to one where code runs only if your policy says so." It complements antivirus rather than replacing it.
- Allowlisting vs blocklisting: a blocklist (deny by exception) blocks named items and allows everything else. It is useful for retiring vulnerable versions or known abuse tools, but it does not stop new malware. NIST SP 800-53 separates the two as CM-7(4) Unauthorized Software, deny by exception, and CM-7(5) Authorized Software, allow by exception.
- What a full policy covers: executables, DLLs, kernel drivers, scripts (PowerShell, VBScript, JScript), MSI installers and packaged apps. Policies that only cover .exe files leave DLL side-loading and script-based attacks open.
- Ringfencing: a term popularised by ThreatLocker for limiting what an allowed application may do once it runs, such as which files, registry keys, network destinations and child processes it can reach. ThreatLocker gives the Follina example, where Word launched MSDT, which launched PowerShell.
- What allowlisting does not stop: abuse of an allowed application with stolen credentials, malicious browser extensions, macros inside allowed Office files (unless script hosts are also controlled), and attacks that never write code to the endpoint, such as session cookie replay from another machine.
Windows options compared
Windows has three built-in application control features that are easy to confuse. App Control for Business is the engine; Smart App Control is a consumer-grade preset built on it; AppLocker is the older, user-aware feature.
| Feature | Scope and strength | Best used for | Main limits |
|---|---|---|---|
| App Control for Business (WDAC) | Whole device, all users, user mode and kernel drivers. Serviced by Microsoft as a security feature. Originally called configurable code integrity, so policies are still code integrity (CI) policies. Supports signed policies, managed installer, Intelligent Security Graph (ISG) and multiple policies from Windows 10 1903. | Primary enforcement on Windows 10, Windows 11 and Windows Server 2016 onwards; managed through Intune, Configuration Manager or PowerShell. | No per-user rules; poorly designed policies can stop boot-critical drivers; needs disciplined change control. |
| AppLocker | Rules per user or group for executables, scripts, MSI, DLLs and packaged apps. Microsoft calls it defence in depth, not a defensible security boundary. Needs the Application Identity service (appidsvc). | Shared computers that need different rules per group; mixed estates with older Windows; fine-tuning on top of an App Control base policy. | Security fixes only, no new features; not supported on Server Core; policies apply only to code launched in a user's context unless extended to SYSTEM processes. |
| Smart App Control | Allows apps predicted safe by Microsoft's cloud service or signed by a certificate in the Trusted Root Program; blocks malware, potentially unwanted apps and unknown unsigned code. | Unmanaged or lightly managed Windows 11 devices. | Only on new Windows 11 installs; turns itself off during evaluation if it sees corporate or developer usage; cannot return to evaluation without a reset. Not an enterprise policy tool. |
| Linux fapolicyd (RHEL) | Trusts binaries in the RPM database plus entries in /etc/fapolicyd/fapolicyd.trust; rules in /etc/fapolicyd/rules.d/. | Servers built from packages, where almost everything should come from the package manager. | No integrity check by default; set integrity = sha256 or ima for stronger assurance. |
Microsoft's own guidance is that organisations able to use App Control should do so, and can then layer AppLocker for user- or group-specific rules where needed. Software Restriction Policies, AppLocker's predecessor, should not be the basis of a new deployment.
Rule types and how they fail
Every allow rule is a trust decision about who can produce code that will run. Pick the level that matches how the software is built and updated, and accept that broader rules trade security for less maintenance.
| App Control rule level | What it trusts | Maintenance | Risk to watch |
|---|---|---|---|
| Hash | One exact file | High: every update changes the hash | Rule sprawl; use for unsigned files and ECDSA-signed files, which signer rules cannot match |
| FilePublisher | Named file from a publisher at or above a version | Low | Good default for third-party software |
| SignedVersion | Any file from a publisher at or above a version | Low | Trusts the publisher's whole catalogue |
| Publisher / PcaCertificate | Everything signed under a certificate authority and leaf name | Very low | Trusts every tool the vendor ships, including ones attackers abuse; a stolen signing key becomes an allow rule |
| LeafCertificate | One signing certificate | Medium: leaf certificates expire often | Breaks on certificate renewal |
| FilePath | Anything in a folder (user mode only, Windows 10 1903 and later) | Very low | Safe only where only administrators can write; App Control checks this at runtime unless option 18 disables the check |
| FileName | Original file name in signed metadata | Low | Weak on its own; combine with publisher |
| Managed installer (option 13) | Files written by a designated deployment agent's process tree | Very low | Heuristic; self-updating apps and extract-and-run installers lose the origin tag; administrators can circumvent |
| ISG (option 14) | Files with a good reputation in Microsoft's Intelligent Security Graph | Very low | Reputation is not organisational approval; use for lightly managed devices, not high-assurance ones |
- Default rule level: generate rules with
-Level FilePublisherand a fallback ofSignedVersion,FilePublisher,Hash, as Microsoft's audit-to-policy example does, then review what the fallback produced. - Path rules done safely: only for admin-writable locations such as
%WINDIR%and%PROGRAMFILES%. Leave runtime FilePath rule protection on. Middle-of-path wildcards (Windows 11 and Server 2025 only) can match user-writable paths you did not intend.
Scripts, living-off-the-land binaries and drivers
A policy that allows all of Windows also allows the Windows tools attackers use to run code without dropping an executable, mapped in MITRE ATT&CK as T1218 System Binary Proxy Execution and T1059 Command and Scripting Interpreter.
- Script enforcement: on by default in App Control unless option 11 (Disabled:Script Enforcement) is set. PowerShell runs disallowed scripts in Constrained Language Mode rather than blocking them; wscript.exe and cscript.exe block disallowed scripts; mshta.exe and MSXML lose all code execution when any script-enforcing policy is active, even in audit mode. Test this early, because audit mode still changes behaviour for these hosts.
- Gaps in script control: cmd.exe batch files are not controlled directly, although what they launch is. Third-party script hosts such as many Python or Java runtimes are not "enlightened", so allowing the interpreter allows every script it runs. Ringfence or restrict those interpreters instead.
- Microsoft recommended block rules: deny binaries that can run arbitrary code unless the business needs them, including mshta.exe, msbuild.exe, wmic.exe, cdb.exe, windbg.exe, kd.exe, dotnet.exe, wsl.exe, wscript.exe and cscript.exe. Merge the list with
Merge-CIPolicyor deploy it as a separate base policy; if merging into an explicit allowlist, first remove the two "allow all" rules (ID_ALLOW_A_1 and ID_ALLOW_A_2). - Drivers: the Microsoft vulnerable driver blocklist is on by default since Windows 11 22H2 and is also enforced with memory integrity (HVCI), Smart App Control or S mode. Pair it with the attack surface reduction rule "Block abuse of exploited vulnerable signed drivers". Managed installer never authorises kernel drivers, so the base policy needs explicit driver rules.
- Office child processes: the attack surface reduction rule "Block all Office applications from creating child processes" is the closest built-in Windows control to ringfencing Office.
Choosing an approach
The right design depends on how software arrives on devices and who decides what runs. Microsoft frames this as defining a "circle of trust" in plain language first, then writing rules to match.
| Situation | Recommended pattern | Trade-off |
|---|---|---|
| Fully managed estate, standard users, all software deployed by Intune or Configuration Manager | App Control base policy from the DefaultWindows template plus managed installer and FilePublisher rules for line-of-business apps | Strong; self-updating apps such as some browsers and collaboration tools need explicit signer rules |
| Teams install their own tools (developers, research) | Common base policy plus team-specific supplemental policies (option 17), and ringfencing for interpreters and build tools | More policies to govern; give each supplemental policy an owner |
| Lightly managed or small organisation with little analyst time | App Control with ISG authorisation (option 14) and the recommended block rules; Smart App Control on new unmanaged Windows 11 devices | Reputation, not approval, decides what runs; still far better than no control |
| Fixed-function servers, kiosks, point of sale, OT workstations | Strict hash or FilePublisher policy, signed, with no managed installer or ISG; fapolicyd with SHA-256 integrity on RHEL | Every change needs a policy update; best ratio of protection to effort |
| Shared devices needing different rules per group, or older Windows versions | AppLocker on top of an App Control base | Two policy sets to maintain |
- Allowlisting vs removing local admin first: do them together, starting with admin removal on the pilot ring. Microsoft warns that "users with administrator privileges, or malware running as an administrator user on the system, may be able to circumvent the intent of your App Control policies" when managed installer is used. Without admin removal, allowlisting is easier to bypass; without allowlisting, standard users can still run unapproved portable tools from their profile.
- Signed policies: signing an App Control policy (removing option 6) stops an administrator from simply deleting it, which matters for high-value servers and privileged access workstations. It also makes mistakes harder to undo, so sign only after the policy is stable.
- Small vs large organisations: a small organisation gets most of the value from ISG plus block rules and admin removal. A large one should invest in supplemental policies per business unit, policy-as-code in version control, and a request process tied to the help desk.
How to implement: from audit to enforcement
- Inventory software and owners. CIS Control 2.1 expects a software inventory; you cannot approve what you have not listed. Record publisher, business purpose and who installs it.
- Remove standing local admin rights for the pilot group and decide how elevation will work (just-in-time elevation or a privileged access workstation). See the Privileged Access Management Guide.
- Write the circle of trust and pick a base template. Start from DefaultWindows (in
%OSDrive%\Windows\schemas\CodeIntegrity\ExamplePolicies), add managed installer for your deployment agent, merge the recommended block rules, and set option 10 (Boot Audit on Failure) and option 16 (Update Policy No Reboot). - Deploy in audit mode (option 3) to a pilot ring of IT staff and a few volunteers from each business unit. Run it for a fixed period that covers month-end and quarterly jobs, not open-ended.
- Build rules from audit events. Collect 3076 and 8028 events centrally, then run
New-CIPolicy -Audit -Level FilePublisher -Fallback SignedVersion,FilePublisher,Hash -UserPEs. Review every generated rule and the warnings file before merging or deploying it as a supplemental policy. - Enforce in rings. Remove option 3 with
Set-RuleOption -Option 3 -Deletefor the pilot, then expand by ring (for example IT, then 10 per cent of users, then business units). Keep audit-mode policies running on the next ring so you see what will break before it does. - Run an exception process with a service level. Requests go through the help desk with a named software owner; approved items become FilePublisher rules in version control, never ad hoc path rules.
- Keep rollback ready and tested. Disable the deployment assignment first so the policy is not pushed again, then remove it with
CiTool.exe -rp "{PolicyId GUID}"(Windows 11 2022 Update and later; unsigned policies can be removed without a restart from the 2024 Update). Signed base policies need a signed replacement with option 6 and a restart, or the device fails to boot. Keep BitLocker recovery keys available for recovery from a boot failure.
On Linux, the same pattern applies with fapolicyd: set permissive = 1 in /etc/fapolicyd/fapolicyd.conf, review denials with ausearch -ts recent -m fanotify, then set permissive = 0 and restart the service.
Detection and measurement
On a well-tuned device a block is rare and worth investigating. Forward these logs to the SIEM from day one of audit mode.
| Event ID | Log | Meaning | Use it to |
|---|---|---|---|
| 3076 | CodeIntegrity/Operational | File would have been blocked (audit mode) | Build rules and size the exception backlog |
| 3077 | CodeIntegrity/Operational | File blocked (enforced) | Alert and triage; repeated blocks on one host suggest an intrusion attempt |
| 3089 | CodeIntegrity/Operational | Signature details for a blocked or audited file | Correlate by Correlation ActivityID to see the signer |
| 3099 | CodeIntegrity/Operational | Policy loaded, with its options | Prove which policy and version is active on each device |
| 3090 / 3091 / 3092 | CodeIntegrity/Operational or Verbose | Allowed by ISG or managed installer / would be blocked (audit) / blocked (enforced) for lack of that authorisation | Check how much you depend on heuristic trust |
| 8028 / 8029 | AppLocker/MSI and Script | Script or MSI would be blocked (audit) / blocked (enforced) | Find unsigned scripts and admin tooling |
| 8002 | AppLocker/EXE and DLL | Process matched a managed installer rule (PolicyName = MANAGEDINSTALLER) | Confirm the deployment agent is recognised |
In Microsoft Defender for Endpoint advanced hunting, managed installer and ISG decisions appear as the action types AppControlCodeIntegrityOriginAllowed, AppControlCodeIntegrityOriginAudited and AppControlCodeIntegrityOriginBlocked.
- Enforcement coverage: percentage of endpoints and servers with an enforced (not audit) policy, by device class. This is the headline metric.
- Policy currency: percentage of devices reporting the current policy version in event 3099.
- Block rate per device: 3077 and 8029 events per enforced device per week; a falling trend shows the policy fits the estate, a spike on one host is an incident lead.
- Exception turnaround: median time from request to approved rule, and the share of rules that are path or hash based.
- Heuristic dependence: share of executions allowed only by ISG or managed installer (3090), which should shrink on high-value systems.
- Admin exposure: number of users with standing local admin on enforced devices, which should trend to zero.
Where identity fits
- Local administrators: admin rights are the main bypass for application control. Remove them, manage local admin passwords with Windows LAPS, and monitor membership of the local Administrators group.
- Code-signing keys are allow rules: a publisher rule trusts whoever holds the signing key. The NVIDIA code-signing certificate theft showed stolen certificates being used to sign malware. Prefer FilePublisher rules with minimum versions, deny revoked signers (option 20 treats revoked certificates as unsigned), and protect your own signing keys as privileged machine identities. See the Machine Identity, PKI and Certificate Lifecycle Guide.
- The deployment agent and its admins: managed installer trusts whatever Intune or Configuration Manager deploys, so the accounts that can publish software or change App Control policy are as powerful as domain administrators. The Stryker Intune wiper attack shows what one hijacked management-plane admin can do. Protect those roles with phishing-resistant MFA, just-in-time access and multi-admin approval where available.
- Service accounts: scheduled tasks and services often run scripts from shares. Sign those scripts and run them from admin-writable locations. See the Service Account Security Guide.
Common failure patterns
- Relying on antivirus alone on high-value endpoints. In the CircleCI breach, malware on an engineer's laptop that antivirus did not detect stole an SSO session. Allowlisting on engineering and admin devices raises the cost of exactly that first step.
- Permanent audit mode. Policies stay in audit for years because nobody owns the switch to enforcement. Set an enforcement date per ring at the start.
- Path rules on user-writable folders. Allowing
%USERPROFILE%\AppDataor a shared tools folder that users can write to lets any dropped file run. Disabling runtime FilePath protection (option 18) to "fix" breakage makes this worse. - Trusting all of a vendor. A broad Microsoft or vendor publisher rule allows mshta.exe, msbuild.exe and old vulnerable versions. Merge the recommended block rules and deny superseded versions.
- Leaving admins in place. Users who remain local administrators can change local policy, remove unsigned App Control policies or abuse managed installer trust.
- Exception sprawl. Every urgent request becomes a hash or path rule with no owner or expiry. Review rules at least twice a year, as CIS safeguards 2.5 to 2.7 expect, and delete those with no recent hits.
Framework mapping
| Framework | Reference | What it asks for |
|---|---|---|
| NIST CSF 2.0 | PR.PS-05 | Installation and execution of unauthorised software are prevented |
| NIST SP 800-53 Rev. 5 | CM-7(5); CM-7(2); CM-7(4) | Deny-all, permit-by-exception for authorised software with periodic review; prevent program execution; deny-by-exception for unauthorised software |
| CIS Controls v8.1 | 2.5, 2.6, 2.7 | Allowlist authorised software, libraries and scripts; reassess at least bi-annually |
| ISO/IEC 27001:2022 Annex A | A.8.19; A.8.7 | Installation of software on operational systems; protection against malware |
| MITRE ATT&CK | M1038 Execution Prevention | Mitigates T1059 Command and Scripting Interpreter, T1218 System Binary Proxy Execution, T1204 User Execution, T1574 Hijack Execution Flow and T1547 Boot or Logon Autostart Execution, among others |
Practitioner checklist
- Maintain a software inventory with a named owner for every approved application.
- Remove standing local admin rights on every device that will be enforced, and manage local admin passwords with LAPS.
- Use App Control for Business as the enforcement layer on Windows; use AppLocker only for per-user rules or older systems.
- Default to FilePublisher rules; allow path rules only for admin-writable locations and keep runtime FilePath protection on.
- Merge Microsoft's recommended block rules and keep the vulnerable driver blocklist enabled.
- Run audit mode with a fixed end date, build rules from 3076 and 8028 events, and enforce in rings.
- Document and test rollback, including signed-policy removal and BitLocker key access.
- Protect the accounts that can deploy software or change App Control policy as privileged identities.
- Forward CodeIntegrity and AppLocker logs to the SIEM and alert on enforced blocks.
- Report enforcement coverage, policy currency and exception turnaround monthly.
Standards and references
- NIST: SP 800-167, Guide to Application Whitelisting
- NIST: SP 800-53 Rev. 5, Security and Privacy Controls for Information Systems and Organizations
- CIS: Critical Security Controls Version 8.1
- MITRE ATT&CK: M1038 Execution Prevention
- Microsoft Learn: App Control for Business and AppLocker overview
- Microsoft Learn: Understanding App Control event IDs
- Microsoft Learn: Applications that can bypass App Control and how to block them
- Microsoft Learn: Allow apps deployed with an App Control managed installer
Related NHI Mgmt Group resources: Privileged Access Management Guide · Machine Identity, PKI and Certificate Lifecycle Guide · Service Account Security Guide · Active Directory and Entra ID Hardening Guide