Skip to content

Least privilege for IIS and Windows services: app pools, gMSA and ACLs

Verified 1 min read

Pick the right service identity, grant only the NTFS rights the app needs, and use gMSA when a domain service account must be managed.

Tested onStandard / Datacenter · Build 26100.33650 · x64
E1
Build
26100.33650
Edition
Standard / Datacenter
Architecture
x64
Support
Documentation (E1)
Evidence
E1Official documentation
Verified
2026-10-29
Page type
Task

Default to ApplicationPoolIdentity for IIS. For a Windows service that needs a domain identity, use gMSA (or a tightly scoped service account), not a domain admin and not LocalSystem.

Grant:

  • read/execute on the app binaries and static files;
  • modify on one upload/cache directory if needed;
  • read on config/secrets the app must read;
  • nothing on C:\, C:\Windows or another app’s folder.
Terminal window
New-WebAppPool -Name 'apppool'
Set-ItemProperty IIS:\AppPools\apppool -Name processModel.identityType -Value ApplicationPoolIdentity
icacls C:\sites\app /grant "IIS AppPool\apppool:(OI)(CI)RX"

For uploads:

Terminal window
icacls C:\sites\app\uploads /grant "IIS AppPool\apppool:(OI)(CI)M"

RX read/execute; M modify. Do not grant F (full) because a vendor installer said so.

If the app runs as a service (Node/Go/Python), create a dedicated local/domain account or gMSA:

  • log on as a service right;
  • read/execute on app dir;
  • write on logs/uploads/temp;
  • no interactive logon;
  • no local admin.
Terminal window
New-ADServiceAccount -Name svc-app -DNSHostName svc-app.example.com `
-PrincipalsAllowedToRetrieveManagedPassword 'IIS-Servers'
Install-ADServiceAccount -Identity svc-app
Test-ADServiceAccount -Identity svc-app

Then set the app pool/service to EXAMPLE\svc-app$ with no password. gMSA requires AD and the KDS root key; it is not a standalone-server feature.

Terminal window
icacls C:\sites\app
Get-IISAppPool apppool | Select-Object Name,State,ProcessModel
whoami /priv

For a service, check Get-CimInstance Win32_Service -Filter "Name='api'" | Select-Object StartName.

  • Everyone read on the site root because one folder failed.
  • App pool in local Administrators “to access a share”.
  • Domain admin for a service that only reads one folder.
  • Shared service account across unrelated apps.
  • Write access to web.config or the PHP/Node binaries.

E1. The lab created labpool with ApplicationPoolIdentity on Windows 11 but did not configure gMSA/AD. The gMSA steps are the domain pattern to validate on Server 2025.

Sources