Repository navigation
fix(agent-installer): stop granting LOCAL SERVICE write access to the data folder - #2173
Merged
Benoît Cortier (CBenoit) merged 7 commits intoOct 28, 2026
Conversation
The Agent data folder gave LOCAL SERVICE write access, so any service running as that account could change what the agent stores there. Only SYSTEM and administrators may. The installer's descriptor for the folder drops the LOCAL SERVICE entry. When the folder already exists, the installer resets its owner and DACL on a handle that holds it, then removes every LOCAL SERVICE allow entry, explicit or inherited, from the DACLs of the files and folders below. Each DACL keeps its other entries, their order and its control flags, and a DACL without such an entry is not written, so the agent's identity folders and files keep exactly the protected DACL it provisions. The walk never follows a link: reparse points are neither followed nor changed, files with more than one hard link are skipped, each directory is held while the entries below it are processed, and a directory replaced during the walk fails it. Issue: DGW-478 Security: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An entry listed below the Agent data folder that can't be opened by the name it was listed under, because it was deleted after the listing or because a Win32 path can't reach its name, such as one ending in a dot, no longer fails the install. Such a name is never created by the installer or the agent, so only an account that could add entries made it, and that account owns it; failing would let one such name block every later upgrade. Every other failure to open an entry still fails the walk. The documentation now states that removing LOCAL SERVICE from the DACLs below the folder leaves owners unchanged, so an entry LOCAL SERVICE created there keeps it as its owner. Issue: DGW-478 Security: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…folder A reparse point below the Agent data folder, such as a junction or a symbolic link, is still never followed, but its own DACL now loses LOCAL SERVICE allow entries like any other entry. Write access on a link lets an account retarget or remove it, which would redirect what the agent writes through it. The link is opened itself, never its target, and a directory link opened again for its security must be the entry first opened, so what it points to is unchanged. A test now checks that a file held open without sharing still loses LOCAL SERVICE, since the agent may hold its files open while the installer runs. Issue: DGW-478 Security: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The walk below the Agent data folder no longer skips a file with more than one hard link: it removes LOCAL SERVICE allow entries from it like any other file. Skipping it let an account that could write a file keep that access by adding a hard link to it, and replacing a file copies its kept entries onto the replacement. A file's security descriptor is shared by all its names, some possibly outside the folder, which is harmless, because removing LOCAL SERVICE allow entries never widens any account's access. Issue: DGW-478 Security: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
EvidenceNo Agent component needs LOCAL SERVICE write access to
Install sequence: I built the MSI locally with MSBuild and read
Tests: Lines changed: 1141 added, 64 removed.
Intent audit of
Deviations
Open questions for the maintainerNone. The owner refusal and the hard-link behaviour are now stated in Decisions and declined review findings
UNTESTED propertiesIntroduced:
Still accurate, unchanged:
Notes
Note LLM-assisted content (no human feedback). |
…trusted owner Earlier installers let LOCAL SERVICE add entries below the Agent data folder, and an entry it created keeps it as the owner, which can always change the entry's DACL whatever the installer sets. Install, upgrade and repair now refuse, with an error in the installer's language naming the entry and its owner, when a file or folder below Agent has an owner other than SYSTEM, Administrators, TrustedInstaller or a member of Administrators. The data folder check walks the entries without changing anything and without following links, before the upgrade removes the installed product. The walk that removes LOCAL SERVICE checks each owner again before it lists a directory or changes a DACL, because the earlier DACL still lets LOCAL SERVICE add entries until the folder is reset. The installer never changes owners below Agent, so a deployment never silently takes over an entry another account created. Issue: DGW-478 Security: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…data folder walk The data folder check now walks the entries below Agent before the upgrade removes the installed product, while the old agent still runs. The agent holds its identity folder without sharing for a moment around each state write, so holding a folder retries a sharing violation for about 2 seconds before it fails the run. A failure to open or hold an entry below Agent, other than one that no longer exists, now names the entry, because the installer log is all an administrator has to find it. Issue: DGW-478 Security: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rules The data folder intent now states that install, upgrade and repair remove the access earlier installers gave LOCAL SERVICE below the folder, hard-linked files included, and refuse an entry below it whose owner isn't trusted rather than take ownership of it. Issue: DGW-478 Security: yes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Benoît Cortier (CBenoit)
deleted the
claude/agent-installer-no-local-service-4232af
branch
October 28, 2026 17:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Agent installer gave LOCAL SERVICE write access to
%ProgramData%\Devolutions\Agent, inherited by every file and folder below it, so any service running as that account could add entries or change files there. No Agent component runs as LOCAL SERVICE or needs that access.The installer now:
pedmsubfolders earlier installers created before lockingpedm;Issue: DGW-478
Security: yes
🤖 Generated with Claude Code