Skip to content

$env:USERDOMAIN is not your identity

env paths · case

bothhard-errorscriptfirst-partyrepro: verifiedenv-derived-identity
Affectsnode, powershell 51, pwsh 7, windows
Fails asACCOUNT SID MAPPING
Mechanismenv derived identity
Safe fixsid principal

An ACL/permissions script builds a principal as "$env:USERDOMAIN\$env:USERNAME" and passes it to icacls. It works on the dev machine, then fails on a renamed computer, a Microsoft-account login, or an AzureAD-joined machine: icacls cannot resolve the principal, the grant fails, and if the code fails closed, the whole feature dies.

Terminal window
# On a workgroup (non-domain) machine:
$env:USERDOMAIN # -> COMPUTERNAME, not a domain
# Microsoft-account login: local profile name != account name
icacls secret.txt /grant "$env:USERDOMAIN\$env:USERNAME:(R)"
# -> "No mapping between account names and security IDs was done."

USERDOMAIN is always set — on a workgroup machine it silently holds the computer name, so domain ? "domain\user" : user fallbacks never fire. Both variables are also plain environment values, writable by whatever launched the process, which makes them attacker-influenceable in a permissions path.

Use the SID, which is what the token actually carries and which icacls accepts directly:

Terminal window
$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
icacls secret.txt /grant "*${sid}:(R)"

The referenced production fix replaced the env-derived principal with the current token’s SID for exactly the failure modes above.