Hmbown/CodeWhale · critical

Codewhale-owned xAI OAuth DACL is not current-user-only

Error message

Codewhale-owned xAI OAuth DACL is not current-user-only

What it means

Windows-only check in verify_windows_owner_only_handle validating the single DACL entry itself. The one ACE must be SID-form (TRUSTEE_IS_SID) with a non-null SID equal to the current user's SID, a grant access mode, and FILE_ALL_ACCESS permissions. Any deviation — a named trustee instead of a SID, a different user/group, SET via deny mode, or reduced permissions — fails this check so xAI OAuth tokens are only ever readable/writable by the owning user.

Solutions

  1. Reset the ACE to the current user with full control: icacls "<path>" /inheritance:r /grant:r "%USERNAME%":F.
  2. If the account SID changed (machine migration, domain re-join), delete the storage and re-run the xAI OAuth login so it is re-provisioned for the new SID.
  3. Remove any hardening script/sync rule that rewrites the ACE, then repair the ACL once.
  4. Report a bug with the icacls output if this occurs on freshly created storage.

Example fix

// before
icacls xai-store
//   CORP\IT-Support:(M)  <-- wrong trustee / reduced rights
// after
icacls xai-store /inheritance:r /grant:r "%USERNAME%":F
Defensive patterns

Strategy: validation

Validate before calling

// Verify the single ACE grants the current user full control via SID
let output = Command::new("icacls").arg(&path).output()?;
// Expect exactly one line of the form:
//   <MACHINE>\<user>:(F)   and no (RX)/(M)/group entries
println!("{}", String::from_utf8_lossy(&output.stdout));

Prevention

When it happens

Trigger: Opening the xAI OAuth store on Windows when the lone ACE grants access to a different principal (another user, a group), uses TRUSTEE_IS_NAME form, uses SET_ACCESS deny semantics, or grants fewer than FILE_ALL_ACCESS — typically after manual icacls edits or ACL restoration by external tools.

Common situations: Admin granted access to an IT group; user lowered permissions to 'read-only' thinking that was safer; a permissions-hardening script rewrote the ACE with a named trustee or subset rights; migration between machines changed the SID (new account) so EqualSid fails.

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/99a21a3452b79781. Report an issue: GitHub.

Appendix: source

Thrown at crates/config/src/xai_credentials.rs:1528

    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-owned xAI OAuth DACL entries");
    }
    let _entries = WindowsLocalAllocation(entries.cast());
    anyhow::ensure!(
        count == 1 && !entries.is_null(),
        "Codewhale-owned xAI OAuth 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();
    // SAFETY: form and null checked in this expression; sid owned by `user`.
    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-owned xAI OAuth 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)