icacls: Set File and Folder Permissions in CI
icacls displays and modifies NTFS access control lists; in CI it fixes "Access is denied" by granting a service account rights or resetting inherited permissions on a working directory.
When a Windows CI step cannot write to a folder, icacls is how you grant the right principal access. The grant/remove/inheritance switches cover almost every case.
What it does
icacls reads or edits the ACL on files and directories. /grant adds a permission for a user or group, /remove revokes one, /inheritance controls whether child items inherit, and /reset restores inherited defaults. /T recurses through the tree.
Common usage
:: grant a service account full control, recursively
icacls "C:\agent\work" /grant "NT AUTHORITY\NetworkService:(OI)(CI)F" /T
:: grant the current user modify rights
icacls .\artifacts /grant "%USERNAME%:(OI)(CI)M" /T
:: reset to inherited permissions
icacls "C:\build" /reset /T
:: view the ACL
icacls "C:\build"Options
| Switch | What it does |
|---|---|
| /grant <user>:<perm> | Add a permission (F=full, M=modify, RX=read+exec) |
| /remove <user> | Remove all ACEs for a user |
| /reset | Replace ACL with inherited permissions |
| /inheritance:e|d|r | Enable, disable, or remove inheritance |
| /T | Apply recursively to the whole tree |
| (OI)(CI) | Object-inherit + container-inherit flags |
In CI
Prefer /grant of the specific service account over disabling inheritance, which can break other tooling. Use (OI)(CI) so new files in the folder inherit the grant. Run the step elevated (or as a member of Administrators) since changing an ACL itself requires permission to do so.
Common errors in CI
"Access is denied." when running icacls means the account lacks rights to change the ACL itself; run elevated or take ownership first (takeown /F path /R). "No mapping between account names and security IDs was done" means the user/group name is wrong or not resolvable on this machine; use a built-in SID like *S-1-5-20 (NetworkService) instead. "The system cannot find the path specified" is a bad target path.