{"record":{"id":"e7f0ab9806e1eb50","repo":"astrid-runtime/astrid","slug":"ordinary-legacy-file-is-group-world-writable-pat","errorCode":null,"errorMessage":"ordinary legacy file is group/world writable: {path}","messagePattern":"ordinary legacy file is group/world writable: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/principal_home_migration/mod.rs","lineNumber":882,"sourceCode":"    if metadata.file_type().is_symlink() || !metadata.is_file() {\n        return Err(invalid_source(path, \"ordinary entry is not a regular file\"));\n    }\n    astrid_core::platform_fs::verify_no_redirects(path)?;\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::MetadataExt as _;\n\n        if metadata.uid() != nix::unistd::getuid().as_raw() {\n            return Err(io::Error::new(\n                io::ErrorKind::PermissionDenied,\n                format!(\n                    \"ordinary legacy file is not owned by the current user: {}\",\n                    path.display()\n                ),\n            ));\n        }\n        if metadata.mode() & 0o022 != 0 {\n            return Err(io::Error::new(\n                io::ErrorKind::PermissionDenied,\n                format!(\n                    \"ordinary legacy file is group/world writable: {}\",\n                    path.display()\n                ),\n            ));\n        }\n    }\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests;\n","sourceCodeStart":864,"sourceCodeEnd":896,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/principal_home_migration/mod.rs#L864-L896","documentation":"Raised by validate_regular_file when an ordinary legacy file is group-writable or world-writable (mode & 0o022 != 0). Overly permissive legacy files are rejected to preserve the private-directory-tree guarantee the migration builds. ErrorKind::PermissionDenied.","triggerScenarios":"Calling digest_file or publish_directory_files (via migrate_legacy_principal_homes) when a regular file's permission mode has group or other write bits set (e.g. 0666, 0664).","commonSituations":"Files shared via group permissions from an old setup, umask-less tools creating 0666 files, legacy homes synced from systems with looser defaults.","solutions":["Tighten permissions: chmod go-w <path> (or chmod 600 for the whole tree)","Run chmod -R go-rwx on the legacy source root before migrating","Check the umask/origin tooling that created 0666 files and fix the source","Re-run migration after the tree satisfies the private-directory requirements"],"exampleFix":"// before: file mode 0664 aborts migration\n-rw-rw-r-- legacy-home/notes.txt\n// after: restrict to owner-only\nchmod 600 legacy-home/notes.txt","handlingStrategy":"validation","validationCode":"#[cfg(unix)]\nfn no_group_world_writable(root: &Path) -> bool {\n    use std::os::unix::fs::PermissionsExt;\n    walk(root).all(|p| p.metadata().map(|m| m.permissions().mode() & 0o022 == 0).unwrap_or(false))\n}","typeGuard":"#[cfg(unix)]\nfn is_owner_writable_only(m: &std::fs::Metadata) -> bool {\n    use std::os::unix::fs::PermissionsExt;\n    m.permissions().mode() & 0o022 == 0\n}","tryCatchPattern":"match migrate(...) {\n    Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {\n        eprintln!(\"tighten modes: chmod -R go-w <legacy home>\");\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["Run chmod -R go-rwx on the legacy tree before migrating","Audit for 0666/0664 files: find <root> -perm -g+w -o -perm -o+w","Set a restrictive umask (077) in tooling that writes legacy homes"],"tags":["permissions","unix","security","file-mode"],"backgroundTag":"permission-denied","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}