Windows sandbox capability SIDs accumulate and appear as Account Unknown in NTFS ACLs

Open 💬 0 comments Opened Aug 27, 2026 by InsecurePassword

Codex Windows sandbox capability SIDs accumulate and appear as unresolved ACL principals

Summary

On Windows 11, the Codex native sandbox persists synthetic capability SIDs in %USERPROFILE%\.codex\cap_sid for global capabilities, workspaces, and writable roots. A full ACL inventory of a multi-project NTFS development tree found that most principals displayed by Windows as Account Unknown were not deleted Windows users: they were exact matches for Codex capability SIDs.

At the time of capture, the Codex ledger contained 404 unique synthetic SIDs:

  • 2 global capability mappings
  • 32 workspace mappings
  • 370 writable-root mappings

The scoped filesystem audit found 58 unresolved SIDs. Of these, 56 matched the Codex capability ledger exactly. The remaining 2 were machine-local test-account residue from a project test suite and were not Codex capability SIDs. Only three actual Codex-managed Windows principals existed: CodexSandboxUsers, CodexSandboxOffline, and CodexSandboxOnline.

This report does not claim that 404 Windows accounts were created. The reported problem is the apparently cumulative persistence of capability-SID mappings and related ACL entries, their presentation as unknown accounts in Windows security tools, and the absence of a clear lifecycle or safe reconciliation path.

Related prior issue

Related but not duplicate: #24256 reported older unresolved S-1-5-21-... sandbox principals and over-broad drive-root ACL grants. This report covers current S-1-15-... capability identities recorded in cap_sid, their Windows Account Unknown presentation, and their lifecycle/idempotence. No over-broad drive-root grant is asserted here.

Environment

  • Windows 11
  • Codex Desktop build: 26.818.8289.0
  • Codex CLI: 0.149.0
  • Native Windows sandbox using NTFS ACL boundaries
  • Multiple independent Codex project roots on one NTFS volume
  • Evidence captured: 2026-08-24

OpenAI's Windows sandbox documentation explains that the elevated sandbox uses dedicated lower-privilege users and filesystem permission boundaries, and that the unelevated implementation also applies ACL-based boundaries. It does not currently explain capability SIDs, how Windows presents them, or their retention and cleanup lifecycle.

User-visible behavior

Windows Advanced Security Settings shows numerous entries such as:

Account Unknown(S-1-15-...)

The number of unknown principals appears to grow during continued Codex use. Because the Windows UI cannot resolve these principals to friendly names, they resemble deleted or orphaned accounts. This can lead operators or support personnel to remove valid sandbox ACEs while attempting to repair permissions.

A prior cleanup attempt did exactly that: capability SIDs were mistaken for orphaned account SIDs. The later audit established that the affected S-1-15-... values were present in the Codex capability ledger.

Impact

  • Windows ACLs become difficult to understand and safely administer.
  • Capability ACEs can be mistaken for stale local-user ACEs.
  • Repeated path-specific mappings can leave multiple generations of Codex-related ACL state across projects.
  • A mistaken cleanup can weaken or break valid sandbox boundaries.
  • Persisted ledger entries that are no longer represented in the audited tree create a stale-state and supportability concern.

No data-loss event or privilege escalation is asserted in this report. A direct causal link between capability-SID accumulation and the separately observed sandbox setup-refresh failures has not been proven.

Evidence

The audit used two independent inputs:

  1. A complete recursive ACL inventory of the authorized development tree, including unresolved owner and ACE SIDs.
  2. The Codex-managed %USERPROFILE%\.codex\cap_sid ledger, parsed into global, workspace, and writable-root mappings.

Results:

| Measurement | Result |
|---|---:|
| Unique synthetic SIDs in Codex ledger | 404 |
| Global mappings | 2 |
| Workspace mappings | 32 |
| Writable-root mappings | 370 |
| Unresolved SIDs in scoped ACL inventory | 58 |
| Exact ledger matches | 56 |
| Other unresolved local-machine SIDs | 2 |
| Unresolved nonlocal SIDs | 0 |
| Ledger SIDs not observed in the scoped tree | 348 |
| SID/ACE removals authorized or performed by this audit | 0 |

The 348 ledger SIDs not observed in this one tree are not claimed to be globally unused; they were simply absent from the audited scope.

Root-cause analysis

Confirmed

  • Codex maintains a persistent capability-SID ledger with distinct entries for global capabilities, workspaces, and writable roots.
  • The captured ledger contained 404 unique synthetic SIDs and 404 mappings.
  • Windows displayed ledger-backed capability SIDs as unresolved principals because they are not local Windows user or group objects.
  • Fifty-six unresolved ACL principals under the audited development tree mapped exactly to the Codex ledger.
  • The two unmatched unresolved SIDs had a separate, locally evidenced project-test origin.

Strong concern, not yet proven as implementation defect

  • The disparity between 404 persisted mappings and 56 mappings observed in the scoped tree suggests that capability state can outlive its immediate ACL use or can refer to paths outside the scanned scope.
  • Repeated sessions, changing writable-root sets, path canonicalization differences, project moves, or update-time state regeneration may contribute to continued growth.
  • There is no operator-visible maintenance command or documented retention policy for determining when a capability SID is still required.

Not established

  • This evidence does not prove that a Codex update alone generated a new SID generation.
  • It does not prove that every ledger-only SID is stale.
  • It does not prove that capability-SID growth directly caused a sandbox initialization failure.
  • It does not justify deleting capability ACEs, ledger entries, or sandbox accounts.

Reproduction / verification

The issue can be verified without changing accounts or ACLs:

  1. On Windows 11, use the native Codex sandbox across multiple project roots and writable-root sets.
  2. Inventory unresolved owner and ACE SIDs under those roots.
  3. Parse %USERPROFILE%\.codex\cap_sid and build the set of global, workspace, and writable-root SIDs.
  4. Compare unresolved ACL SIDs to that set.
  5. Record the unique ledger count across ordinary Codex restarts and updates while keeping the same canonical project roots.
  6. Verify whether unchanged roots reuse existing mappings or add new mappings, and whether removed roots are ever reconciled.

A local audit tool performed steps 2 through 4 read-only with respect to accounts, ACLs, configuration, and project content.

Expected behavior

  • Capability identities and mappings should be idempotent for unchanged canonical roots across restarts and updates.
  • Obsolete mappings and ACEs should have a documented, safe, transactional reconciliation lifecycle.
  • Codex diagnostics should identify these values as Codex capability SIDs rather than leaving operators to interpret Account Unknown entries.
  • An update should preserve or migrate still-valid capability state without producing unnecessary new generations.
  • Documentation should explain which SIDs are real sandbox accounts, which are capability SIDs, and which cleanup actions are unsafe.

Actual behavior

  • The local Codex ledger accumulated 404 synthetic SIDs.
  • Windows displayed Codex capability ACE principals as unknown accounts.
  • Fifty-six such principals remained in ACLs within the audited development tree.
  • Operators had no supported way to distinguish valid, currently referenced, and stale capability entries before performing repair work.

Requested engineering changes

  1. Make capability mapping reuse stable and idempotent for canonical-equivalent workspace and writable-root paths.
  2. Add an update-safe reconciliation step that can distinguish active mappings from obsolete mappings without weakening existing sandbox boundaries.
  3. Do not delete or replace capability ACEs until replacement state is committed and rollback is possible.
  4. Add a diagnostic command that reports capability type, canonical path, active-reference status, ACL reference count, and creation/update generation without exposing unrelated user data.
  5. Warn when ledger size grows unexpectedly for unchanged roots.
  6. Document capability SIDs and their expected lifecycle in the Windows sandbox documentation.
  7. Add regression tests covering repeated setup, restart, application update, path case/separator variants, moved roots, removed roots, and rollback after interrupted reconciliation.

Local remediation performed

No capability SIDs, accounts, ledger entries, or capability ACEs were deleted in this audit. Capability-backed unresolved SIDs were classified as Codex-managed and retained unless a specific ACE was independently proven broken by separate evidence.

Additional evidence available through a private channel

  • Aggregated SID-adjudication summary
  • Redacted capability-ledger counts and mapping categories
  • Redacted unresolved-SID classification with paths and raw machine identifiers removed or tokenized
  • Read-only audit methodology and tool

Do not attach the raw capability ledger or unredacted filesystem paths. Do not include user names, machine names, email addresses, thread IDs, or unrelated project content.

No raw capability ledger, ACL descriptor, filesystem path inventory, SID values, session records, credentials, or project content is included in this public report.

View original on GitHub ↗