{"record":{"id":"ba9f6fe23668db01","repo":"Hmbown/CodeWhale","slug":"codewhale-owned-credential-file-dacl-is-not-curren","errorCode":null,"errorMessage":"Codewhale-owned credential file DACL is not current-user-only","messagePattern":"Codewhale-owned credential file DACL is not current-user-only","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/external_credentials.rs","lineNumber":505,"sourceCode":"    }\n    let _entries = WindowsLocalAllocation(entries.cast());\n    if count != 1 || entries.is_null() {\n        return Err(io::Error::new(\n            io::ErrorKind::PermissionDenied,\n            \"Codewhale-owned credential file DACL must grant only one user\",\n        ));\n    }\n    // SAFETY: `count == 1` proves the first returned entry is initialized.\n    let entry = unsafe { &*entries };\n    let trustee_sid: PSID = entry.Trustee.ptstrName.cast();\n    // SAFETY: form and null checked in this expression; sid owned by `user`.\n    let current_user_only = entry.Trustee.TrusteeForm == TRUSTEE_IS_SID\n        && !trustee_sid.is_null()\n        && unsafe { EqualSid(trustee_sid, user.sid()) } != 0\n        && matches!(entry.grfAccessMode, SET_ACCESS | GRANT_ACCESS)\n        && entry.grfAccessPermissions == FILE_ALL_ACCESS;\n    if !current_user_only {\n        return Err(io::Error::new(\n            io::ErrorKind::PermissionDenied,\n            \"Codewhale-owned credential file DACL is not current-user-only\",\n        ));\n    }\n    Ok(())\n}\n\n#[cfg(windows)]\nstruct CurrentWindowsUser {\n    token: windows_sys::Win32::Foundation::HANDLE,\n    token_info: Vec<usize>,\n}\n\n#[cfg(windows)]\nimpl CurrentWindowsUser {\n    fn open() -> io::Result<Self> {\n        use windows_sys::Win32::Foundation::{GetLastError, HANDLE};\n        use windows_sys::Win32::Security::{","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/external_credentials.rs#L487-L523","documentation":"This error means the Windows discretionary access control list (DACL) on a Codewhale-owned credential file grants access beyond the current user, so the file fails the strict owner-only verification. The library throws it when opening the credential file with require_owner_only=true, after enumerating every ACE and failing to find exactly one access-allowed ACE granting FILE_ALL_ACCESS to the current user's SID via TRUSTEE_IS_SID.","triggerScenarios":"Calling read_codewhale_owned_to_string on a credential file whose DACL was modified (extra ACEs added, permissions narrowed, or trustee expressed as a name rather than SID), so no single ACE matches the current-user-only pattern.","commonSituations":"File permissions edited manually or by a sync/backup tool that rewrote the ACL; the file was copied from another location preserving broader ACLs; an administrator or installer changed the DACL; the file was created by a different security context.","solutions":["Recreate the credential file so Codewhale rewrites it with a current-user-only DACL (delete the file and re-authenticate or re-run the credential setup)","Remove extra ACEs and ensure a single GRANT/SET_ACCESS ACE gives the current user SID FILE_ALL_ACCESS (icacls <file> /inheritance:r /grant:r \"%USERNAME%:F\")","Copy the file to a fresh location so it inherits a default user-only ACL, then point the config at it"],"exampleFix":"// before (broad ACL)\nicacls cred.json /grant Users:F\n// after\nicacls cred.json /inheritance:r /grant:r \"%USERNAME%:F\"","handlingStrategy":"validation","validationCode":"// Windows: check the ACL before relying on the file\nuse std::os::windows::fs::MetadataExt;\nlet md = std::fs::metadata(path)?; // plus icacls/SDDL parse if you need full certainty\nif !md.permissions().readonly() { /* run: icacls <path> to inspect ACEs */ }","typeGuard":null,"tryCatchPattern":"match std::fs::read(path) {\n    Ok(data) => use_credential(&data),\n    Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {\n        eprintln!(\"credential file ACL not user-only; re-run credential setup\");\n        repair_dacl(path);\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Never copy credential files with tools that preserve broad ACLs; recreate them via Codewhale","Run icacls <file> /inheritance:r /grant:r \"%USERNAME%:F\" after any manual restore","Avoid syncing credential directories with backup/DACL-rewriting tools","Verify ACLs after OS upgrades or profile migration"],"tags":["windows","security","file-permissions","credentials"],"backgroundTag":"insufficient-permissions","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}