{"record":{"id":"5e8092803b914dae","repo":"astrid-runtime/astrid","slug":"principal-store-capability-entry-is-redirected-or-5e8092","errorCode":null,"errorMessage":"principal-store capability entry is redirected or not a regular file","messagePattern":"principal-store capability entry is redirected or not a regular file","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/astrid-storage/src/engine/durable/native_io.rs","lineNumber":178,"sourceCode":"        use cap_std::fs::OpenOptionsExt as _;\n        options.custom_flags(libc::O_NOFOLLOW | libc::O_NONBLOCK);\n    }\n    #[cfg(windows)]\n    {\n        use cap_std::fs::OpenOptionsExt as _;\n        use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_OPEN_REPARSE_POINT;\n        options.custom_flags(FILE_FLAG_OPEN_REPARSE_POINT);\n    }\n}\n\nfn validate_regular(file: &NativeFile) -> Result<(), DurableError> {\n    let metadata = file\n        .metadata()\n        .map_err(|source| io_error(\"inspect principal-store capability file\", source))?;\n    if !metadata.is_file() || file_is_redirected(&metadata) {\n        return Err(io_error(\n            \"validate principal-store capability file\",\n            io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"principal-store capability entry is redirected or not a regular file\",\n            ),\n        ));\n    }\n    Ok(())\n}\n\n#[cfg(windows)]\nfn file_is_redirected(metadata: &std::fs::Metadata) -> bool {\n    use std::os::windows::fs::MetadataExt as _;\n    use windows_sys::Win32::Storage::FileSystem::FILE_ATTRIBUTE_REPARSE_POINT;\n\n    metadata.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT != 0\n}\n\n#[cfg(not(windows))]\nconst fn file_is_redirected(_metadata: &std::fs::Metadata) -> bool {","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage/src/engine/durable/native_io.rs#L160-L196","documentation":"validate_regular checks that an opened principal-store capability file is a real regular file and not a symlink or redirected entry; on failure it raises this InvalidData error. Like the directory check, it guarantees the store never reads or writes through redirected file entries. The wrapper text \"inspect principal-store capability file\" propagates the underlying metadata error if stat fails.","triggerScenarios":"Calling open_rw or create_private on a path where the entry is a symlink, device node, FIFO, or directory instead of a regular file; or where file_is_redirected detects redirection metadata on the opened handle.","commonSituations":"A developer symlinked a data file to shared storage; a tooling bug replaced a file with a FIFO/socket; tampering attempts inside a world-writable store directory.","solutions":["Remove the symlink or non-regular entry and restore a real regular file at that path","Copy the target data back into a genuine file inside the store instead of linking to it","Restrict write access to the store root to prevent symlink planting","Re-run store integrity checks after fixing the entry"],"exampleFix":"// before\nln -s /shared/blob store/principals/tenant-a/data.bin\n// after\nrm store/principals/tenant-a/data.bin && cp /shared/blob store/principals/tenant-a/data.bin","handlingStrategy":"validation","validationCode":"fn assert_regular_file(p: &Path) -> io::Result<()> {\n    let md = p.symlink_metadata()?;\n    if !md.is_file() || md.file_type().is_symlink() {\n        return Err(io::Error::new(io::ErrorKind::InvalidData, \"not a regular file\"));\n    }\n    Ok(())\n}","typeGuard":"fn is_plain_file(p: &Path) -> bool {\n    std::fs::symlink_metadata(p).map(|m| m.is_file() && !m.file_type().is_symlink()).unwrap_or(false)\n}","tryCatchPattern":"match open_rw_result {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => {\n        // restore a real regular file at the path, then retry\n    }\n    r => r,\n}","preventionTips":["Never replace store files with symlinks, FIFOs, or device nodes","Restrict write access to capability directories","Validate entries with symlink_metadata before opening the store","Investigate immediately — this check failing often signals tampering or tooling bugs"],"tags":["io","filesystem","symlink","security"],"backgroundTag":"symlink-detected-in-path","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"}