{"record":{"id":"d060ed8f98314ec1","repo":"Hmbown/CodeWhale","slug":"codewhale-owned-credential-file-must-have-an-owner-only-dacl","errorCode":null,"errorMessage":"Codewhale-owned credential file must have an owner-only DACL","messagePattern":"Codewhale-owned credential file must have an owner-only DACL","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/external_credentials.rs","lineNumber":475,"sourceCode":"            std::ptr::null_mut(),\n            &mut dacl,\n            std::ptr::null_mut(),\n            &mut descriptor,\n        )\n    };\n    if result != ERROR_SUCCESS {\n        return Err(io::Error::from_raw_os_error(result as i32));\n    }\n    let _descriptor = WindowsLocalAllocation(descriptor.cast());\n    // SAFETY: `owner` is non-null; `user.sid()` is owned by `user`.\n    if owner.is_null() || unsafe { EqualSid(owner, user.sid()) } == 0 {\n        return Err(io::Error::new(\n            io::ErrorKind::PermissionDenied,\n            \"Codewhale-owned credential file owner is not the current user\",\n        ));\n    }\n    if dacl.is_null() {\n        return Err(io::Error::new(\n            io::ErrorKind::PermissionDenied,\n            \"Codewhale-owned credential file must have an owner-only DACL\",\n        ));\n    }\n    let mut count = 0;\n    let mut entries: *mut EXPLICIT_ACCESS_W = std::ptr::null_mut();\n    // SAFETY: `dacl` is owned by the live security descriptor; Windows\n    // allocates the returned entries, released below.\n    let result = unsafe { GetExplicitEntriesFromAclW(dacl, &mut count, &mut entries) };\n    if result != ERROR_SUCCESS {\n        return Err(io::Error::from_raw_os_error(result as i32));\n    }\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        ));","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/external_credentials.rs#L457-L493","documentation":"After confirming the owner, verify_windows_owner_only_handle requires the file to have a discretionary ACL (DACL) at all. A null DACL means access is governed by inherit-only rules or (in the SE_DACL_PRESENT-less case) that everyone may access the object; the library throws PermissionDenied because an owner-only guarantee cannot be verified without an explicit DACL.","triggerScenarios":"read_codewhale_owned_to_string opens a credential file whose security descriptor has no DACL / a null DACL — e.g. the ACL was stripped, the file was created on a filesystem without ACL enforcement and later moved, or `icacls /reset` removed explicit entries.","commonSituations":"File copied from a FAT/exFAT volume (no ACLs) to NTFS; a backup/restore tool dropped the security descriptor; `icacls <file> /remove` removed all ACEs; file was created in a directory whose inheritance produced no explicit DACL.","solutions":["Set an explicit owner-only DACL: `icacls <file> /inheritance:r /grant:r \"%USERNAME%:F\"`.","Recreate the file in place so Windows assigns a default secure DACL.","Verify with `icacls <file>` that an explicit ACL listing only your user exists.","Avoid moving credential files from non-ACL filesystems without resetting permissions."],"exampleFix":":: before\nicacls C:\\Users\\me\\.codewhale\\token.json   :: No DACL / inherited nothing\n:: after\nicacls C:\\Users\\me\\.codewhale\\token.json /inheritance:r /grant:r \"%USERNAME%:F\"","handlingStrategy":"validation","validationCode":"// PowerShell pre-check: an explicit DACL must exist\n// $acl = Get-Acl $path; $acl.GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier]).Count -ge 1","typeGuard":null,"tryCatchPattern":"match read_codewhale_owned_to_string(&path) {\n    Ok(creds) => use(creds),\n    Err(e) if e.to_string().contains(\"owner-only DACL\") => {\n        eprintln!(\"set explicit ACL: icacls {p} /inheritance:r /grant:r %USERNAME%:F\", p = path.display());\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always set an explicit ACL on credential files: icacls <file> /inheritance:r /grant:r \"%USERNAME%:F\".","Do not move credential files from FAT/exFAT (no ACLs) without resetting permissions.","Check ACLs survive backup/restore cycles; restore tools can drop descriptors.","Verify with `icacls <file>` that explicit rules exist before first use."],"tags":["windows","security","acl","dacl","credentials"],"backgroundTag":"permission-denied","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"}