Skip to content

[Bug][Windows] ACL hardening trusts USERDOMAIN and rejects workgroup local accounts #1149

Description

@luvs01

Client or integration

Other — OpenCodex proxy/service startup and file-backed management authentication on Windows

Area

Platform (Windows / macOS / Linux)

Summary

On a Windows workgroup host, USERDOMAIN can be the literal WORKGROUP while the effective token belongs to the local computer account (for example, COMPUTER\\user). The current src/lib/windows-secret-acl.ts builds the owner ACE from USERDOMAIN\\USERNAME, so it asks icacls to grant an unmappable WORKGROUP\\user principal.

On the reproduced host, that grant exits with code 52. Required ACL hardening then correctly fails closed, but native-main ownership or file-backed management authentication becomes unavailable even though the NTFS volume and the effective account are valid.

Expected: derive the ACL principal from the effective Windows token, preferably its locale-independent SID, rather than from environment strings.

Reproduction

  1. On a Windows machine joined only to a workgroup, compare the environment-derived principal with the effective token:
    $environmentPrincipal = "$env:USERDOMAIN\$env:USERNAME"
    $token = [Security.Principal.WindowsIdentity]::GetCurrent()
    $environmentPrincipal
    $token.Name
  2. Create a temporary file and run the same owner grant shape used by currentWindowsUser():
    $probe = New-TemporaryFile
    icacls.exe $probe /grant:r "${environmentPrincipal}:(F)"
    $environmentExit = $LASTEXITCODE
  3. On the affected host, the environment principal is WORKGROUP\\user and the command exits 52.
  4. Grant the effective token SID instead:
    icacls.exe $probe /grant:r "*$($token.User.Value):(F)"
    $sidExit = $LASTEXITCODE
    Remove-Item -LiteralPath $probe
  5. The SID grant exits 0. The same distinction reproduces through OpenCodex's required ACL hardening path.

Version

2.10.2; also present on current dev at e9d957bf67d05cdb09c84dbac8d436a349d308f1

Operating system

Windows 11, build 26200

Provider and model

Not provider-specific

Logs or error output

environment principal: WORKGROUP\\<redacted-user>
effective token name: <redacted-computer>\\<redacted-user>
environment-principal icacls exit: 52
effective-token SID icacls exit: 0

Screenshots and supporting files

No screenshot is required; the reproduction above uses a disposable temporary file and redacts account identifiers.

Redacted configuration

{
  "configuration_dependency": "none"
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Root cause and proposed boundary

currentWindowsUser() in src/lib/windows-secret-acl.ts treats USERDOMAIN\\USERNAME as an account authority. Those variables are not an authoritative representation of the effective token.

A focused fix can:

  • resolve WindowsIdentity.GetCurrent().User.Value;
  • validate and pass the SID to icacls as *S-1-...:(F);
  • launch trusted System32 PowerShell hidden, non-interactive, and within the existing ACL deadline;
  • process-cache only a successful SID lookup;
  • classify lookup failure separately from an icacls timeout so the destination timeout memo is not polluted.

This is distinct from #160/#612/#766 (timeout, async waiting, and fail-closed availability) and #596/#601 (owner-ACE ordering). PR #998 introduced token-SID identity for Codex coordinator state, but the ACL principal path still independently uses the environment-derived name.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions