{"record":{"id":"44171684697ddcc1","repo":"astrid-runtime/astrid","slug":"named-pipe-peer-process-belongs-to-a-different-ope","errorCode":null,"errorMessage":"named-pipe peer process belongs to a different operating-system user","messagePattern":"named-pipe peer process belongs to a different operating-system user","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-core/src/local_transport/windows.rs","lineNumber":461,"sourceCode":"    let mut token = ptr::null_mut();\n    let opened = unsafe { OpenProcessToken(process.0, TOKEN_QUERY, &raw mut token) };\n    if opened == 0 || token.is_null() {\n        return Err(last_error(\"failed to open named-pipe peer process token\"));\n    }\n    let user_sid = token_user_sid(&OwnedHandle(token))?;\n    Ok(VerifiedPeerProcess {\n        process_id,\n        user_sid,\n        _process: process,\n    })\n}\n\nfn require_current_user_process_peer(stream: &LocalStream) -> io::Result<VerifiedPeerProcess> {\n    let peer = peer_process_identity(stream)?;\n    if peer.user_sid.equals(&current_user_sid()?) {\n        Ok(peer)\n    } else {\n        Err(io::Error::new(\n            io::ErrorKind::PermissionDenied,\n            \"named-pipe peer process belongs to a different operating-system user\",\n        ))\n    }\n}\n\nfn require_current_user_effective_client(stream: &LocalStream) -> io::Result<()> {\n    let client_sid = effective_client_user_sid(stream)?;\n    if client_sid.equals(&current_user_sid()?) {\n        Ok(())\n    } else {\n        Err(io::Error::new(\n            io::ErrorKind::PermissionDenied,\n            \"named-pipe client's effective token belongs to a different operating-system user\",\n        ))\n    }\n}\n","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-core/src/local_transport/windows.rs#L443-L479","documentation":"require_current_user_process_peer compares the peer process's owner SID with the local process's user SID and rejects the connection when they differ. This enforces same-user-only IPC over named pipes, preventing other accounts (or privilege-escalating sessions) from talking to your pipe server.","triggerScenarios":"Calling connect or accept where the client process runs as a different OS user (different account, service account vs. interactive user, elevated vs. standard session mapping to different SIDs).","commonSituations":"A Windows service (LocalSystem) hosting the pipe while a desktop user app connects; running the client under 'Run as administrator' with a split-token admin SID; connecting across user sessions (RDP vs. console).","solutions":["Run the client and server under the same Windows user account.","Avoid mixing elevation states — run both sides elevated or both non-elevated.","If cross-user IPC is genuinely required, use a transport designed for it (e.g. TCP on localhost with explicit auth) instead of this same-user pipe."],"exampleFix":"// before (client launched as another user)\nProcess.Start(new ProcessStartInfo { UserName = \"svc\", ... });\n// after\n// launch client as the same interactive user as the pipe server\nProcess.Start(new ProcessStartInfo { UseShellExecute = true, FileName = \"client.exe\" });","handlingStrategy":"validation","validationCode":"// before connecting, compare SIDs on both sides via whoami /user\n// or in Rust: assert current_user_sid() equals the account the client runs under","typeGuard":"fn same_user(peer_sid: &Sid, current: &Sid) -> bool { peer_sid.equals(current) }","tryCatchPattern":"match listener.accept() {\n    Err(e) if e.kind() == io::ErrorKind::PermissionDenied\n        && e.to_string().contains(\"different operating-system user\") => {\n        eprintln!(\"peer ran as another user; reject and keep listening\");\n    }\n    other => other?,\n}","preventionTips":["Run client and server under the same Windows account.","Match elevation levels on both sides (both elevated or neither).","Document the same-user requirement in deployment/service config."],"tags":["windows","named-pipes","security","authentication","user-sid"],"backgroundTag":"permission-denied","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}