Hmbown/CodeWhale · error

Codewhale issue-report DACL is not current-user-only

Error message

Codewhale issue-report DACL is not current-user-only

What it means

The DACL has exactly one entry, but that entry is not an unconditional grant of FILE_ALL_ACCESS to the current user's SID: the trustee is not SID-form, the SID is null or differs from the caller's, the access mode is not SET/GRANT, or permissions differ from FILE_ALL_ACCESS. The handle is therefore not provably current-user-only and is rejected.

Solutions

  1. Recreate the issue-report handle so Codewhale builds the DACL itself with EqualSid-verified current-user SID and FILE_ALL_ACCESS
  2. Normalize the ACE: `icacls <path> /inheritance:r /grant:r *<current-user-SID>:F`
  3. Confirm the process is running as the same user that created the handle (check elevation/service account)
  4. Audit tools (AV, EDR, group policy) that rewrite ACEs on the temp/report directory

Example fix

// before
icacls report.txt /grant:r BUILTIN\Users:F
// after
icacls report.txt /inheritance:r /grant:r "%USERNAME%":F
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the single ACE is the current user with full control
$a = (Get-Acl $path).Access[0]; $a.IdentityReference.Value -eq $env:USERNAME -and $a.FileSystemRights -eq 'FullControl'

Try / catch

if let Err(e) = verify_windows_owner_only_handle(h) { if e.to_string().contains("current-user-only") { recreate_handle(); } }

Prevention

When it happens

Trigger: An ACE grants access to a group or name-mapped trustee instead of the user's SID; the DACL grants a narrower permission mask (e.g. FILE_GENERIC_WRITE); a DENY ACE replaced the grant; or a different account's SID was embedded when the handle was created.

Common situations: Handle created under a service account then used by the logged-in user; DACL edited with icacls using name-based trustees that map to groups; running elevated vs non-elevated so the effective user SID differs; sandboxing software rewriting ACEs.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/721c832442765bec. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/github/report.rs:1098

        );
        let mut count = 0;
        let mut entries: *mut EXPLICIT_ACCESS_W = std::ptr::null_mut();
        // SAFETY: `dacl` belongs to the live descriptor; Windows allocates the
        // returned entry array, released by the guard below.
        let result = unsafe { GetExplicitEntriesFromAclW(dacl, &mut count, &mut entries) };
        if result != ERROR_SUCCESS {
            return Err(std::io::Error::from_raw_os_error(result as i32))
                .context("reading Codewhale issue-report DACL entries");
        }
        let _entries = WindowsLocalAllocation(entries.cast());
        anyhow::ensure!(
            count == 1 && !entries.is_null(),
            "Codewhale issue-report DACL must grant only one user"
        );
        // SAFETY: `count == 1` proves the first returned entry is initialized.
        let entry = unsafe { &*entries };
        let trustee_sid: PSID = entry.Trustee.ptstrName.cast();
        anyhow::ensure!(
            entry.Trustee.TrusteeForm == TRUSTEE_IS_SID
                && !trustee_sid.is_null()
                && unsafe { EqualSid(trustee_sid, user.sid()) } != 0
                && matches!(entry.grfAccessMode, SET_ACCESS | GRANT_ACCESS)
                && entry.grfAccessPermissions == FILE_ALL_ACCESS,
            "Codewhale issue-report DACL is not current-user-only"
        );
        Ok(())
    }

    #[cfg(windows)]
    struct CurrentWindowsUser {
        token: windows_sys::Win32::Foundation::HANDLE,
        token_info: Vec<usize>,
    }

    #[cfg(windows)]
    impl CurrentWindowsUser {

View on GitHub (pinned to 73e0f67d83)