{"record":{"id":"81ef4be0210ae302","repo":"openai/codex","slug":"platform-default-filesystem-permissions-cannot-be","errorCode":null,"errorMessage":"platform-default filesystem permissions cannot be intersected safely","messagePattern":"platform-default filesystem permissions cannot be intersected safely","errorType":"exception","errorClass":"PermissionIntersectionError","httpStatus":null,"severity":"error","filePath":"codex-rs/protocol/src/permission_profile_intersection.rs","lineNumber":25,"sourceCode":"use crate::models::PermissionProfile;\nuse crate::permissions::FileSystemAccessMode;\nuse crate::permissions::FileSystemPath;\nuse crate::permissions::FileSystemSandboxEntry;\nuse crate::permissions::FileSystemSandboxKind;\nuse crate::permissions::FileSystemSandboxPolicy;\nuse crate::permissions::FileSystemSpecialPath;\nuse crate::permissions::NetworkSandboxPolicy;\nuse crate::permissions::PROTECTED_METADATA_PATH_NAMES;\nuse crate::permissions::ReadDenyMatcher;\nuse crate::permissions::default_read_only_subpaths_for_writable_root;\nuse crate::permissions::project_roots_glob_pattern;\n\n/// A policy cannot be intersected without weakening either input.\n#[derive(Clone, Debug, Eq, Error, PartialEq)]\npub enum PermissionIntersectionError {\n    #[error(\"externally enforced filesystem permissions cannot be intersected safely\")]\n    ExternalSandbox,\n    #[error(\"platform-default filesystem permissions cannot be intersected safely\")]\n    PlatformDefaults,\n    #[error(\"unsupported permission path: {0}\")]\n    UnsupportedPath(String),\n}\n\n/// Intersects already-effective filesystem permissions and network access.\n///\n/// Both profiles must already be materialized for the same local executor and\n/// cwd. Concrete grant paths are canonicalized before comparison and in the\n/// result, so symlinks cannot acquire authority beyond either input.\n/// Unsupported policy shapes fail closed.\npub fn intersect_effective_permission_profiles(\n    authority: &PermissionProfile,\n    requested: &PermissionProfile,\n    cwd: &Path,\n) -> Result<PermissionProfile, PermissionIntersectionError> {\n    if matches!(authority, PermissionProfile::External { .. })\n        || matches!(requested, PermissionProfile::External { .. })","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/protocol/src/permission_profile_intersection.rs#L7-L43","documentation":"PermissionIntersectionError::PlatformDefaults (codex-rs/protocol/src/permission_profile_intersection.rs:25-26) is raised inside normalize_policy (lines 277-279, and for FileSystemSpecialPath::Minimal at 339-341) when a policy being intersected still includes platform defaults - include_platform_defaults() is true or the Minimal special path is present. Platform defaults resolve per-OS and per-executor, so an intersection could silently diverge from what either input actually grants; the merge fails closed.","triggerScenarios":"intersect_effective_permission_profiles on two differing, non-Unrestricted, non-Disabled profiles where either side was built with include_platform_defaults = true or carries the Minimal special path.","commonSituations":"User configs layering grants on top of OS defaults; cross-platform configs where defaults differ; profiles forwarded to intersection without being materialized for the concrete executor.","solutions":["Materialize platform defaults for the concrete executor and OS into explicit policy entries before intersecting.","Rebuild the profile with include_platform_defaults off once defaults are expanded.","Replace FileSystemSpecialPath::Minimal with its concrete entry set before merging."],"exampleFix":"// before:\nlet merged = intersect_effective_permission_profiles(&a, &b, &cwd)?;\n// a.include_platform_defaults() == true -> PlatformDefaults error\n\n// after: expand defaults into concrete entries, then intersect\nlet a = materialize_platform_defaults(a, &cwd)?; // no platform defaults left\nlet merged = intersect_effective_permission_profiles(&a, &b, &cwd)?;","handlingStrategy":"validation","validationCode":"if authority.file_system_sandbox_policy().include_platform_defaults()\n    || requested.file_system_sandbox_policy().include_platform_defaults()\n{\n    // expand platform defaults into explicit entries before intersecting\n}","typeGuard":"fn includes_platform_defaults(p: &PermissionProfile) -> bool {\n    p.file_system_sandbox_policy().include_platform_defaults()\n}","tryCatchPattern":"Err(PermissionIntersectionError::PlatformDefaults) => {\n    // expand defaults for this executor and retry the intersection once\n}","preventionTips":["Always materialize profiles for the target executor before merging.","Keep intersection inputs free of Minimal and platform-default markers.","Add tests covering the platform-default path on each supported OS."],"tags":["rust","codex","sandbox","permissions","platform-defaults"],"backgroundTag":"sandbox-policy-intersection-failed","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}