openai/codex · error · PermissionIntersectionError

externally enforced filesystem permissions cannot be interse

Error message

externally enforced filesystem permissions cannot be intersected safely

What it means

PermissionIntersectionError::ExternalSandbox (codex-rs/protocol/src/permission_profile_intersection.rs:23-24) is returned by intersect_effective_permission_profiles when either input is PermissionProfile::External - permissions enforced by a sandbox outside Codex's own policy engine. As the module doc states, such a policy cannot be intersected without weakening an input, so the merge fails closed (checked first, at lines 42-46).

Source

Thrown at codex-rs/protocol/src/permission_profile_intersection.rs:23

use thiserror::Error;

use crate::models::PermissionProfile;
use crate::permissions::FileSystemAccessMode;
use crate::permissions::FileSystemPath;
use crate::permissions::FileSystemSandboxEntry;
use crate::permissions::FileSystemSandboxKind;
use crate::permissions::FileSystemSandboxPolicy;
use crate::permissions::FileSystemSpecialPath;
use crate::permissions::NetworkSandboxPolicy;
use crate::permissions::PROTECTED_METADATA_PATH_NAMES;
use crate::permissions::ReadDenyMatcher;
use crate::permissions::default_read_only_subpaths_for_writable_root;
use crate::permissions::project_roots_glob_pattern;

/// A policy cannot be intersected without weakening either input.
#[derive(Clone, Debug, Eq, Error, PartialEq)]
pub enum PermissionIntersectionError {
    #[error("externally enforced filesystem permissions cannot be intersected safely")]
    ExternalSandbox,
    #[error("platform-default filesystem permissions cannot be intersected safely")]
    PlatformDefaults,
    #[error("unsupported permission path: {0}")]
    UnsupportedPath(String),
}

/// Intersects already-effective filesystem permissions and network access.
///
/// Both profiles must already be materialized for the same local executor and
/// cwd. Concrete grant paths are canonicalized before comparison and in the
/// result, so symlinks cannot acquire authority beyond either input.
/// Unsupported policy shapes fail closed.
pub fn intersect_effective_permission_profiles(
    authority: &PermissionProfile,
    requested: &PermissionProfile,
    cwd: &Path,
) -> Result<PermissionProfile, PermissionIntersectionError> {

View on GitHub (pinned to 339751715c)

Solutions

  1. Do not intersect External profiles: use the stricter of the two profiles directly instead of merging.
  2. Materialize both sides into concrete runtime permission profiles resolved for the same executor and cwd, then intersect - the function expects already-materialized inputs.
  3. If you own the outer sandbox, express its restrictions as an explicit FileSystemSandboxPolicy rather than External.

Example fix

// before:
let combined = intersect_effective_permission_profiles(&authority, &requested, &cwd)?;
// authority is PermissionProfile::External -> ExternalSandbox error

// after: branch before intersecting
let combined = if matches!(authority, PermissionProfile::External { .. })
    || matches!(requested, PermissionProfile::External { .. })
{
    stricter_of(authority, requested) // no intersection for external sandboxes
} else {
    intersect_effective_permission_profiles(&authority, &requested, &cwd)?
};
Defensive patterns

Strategy: type-guard

Validate before calling

if matches!(authority, PermissionProfile::External { .. })
    || matches!(requested, PermissionProfile::External { .. })
{
    // skip intersection; enforce the stricter profile as-is
}

Type guard

fn is_external(p: &PermissionProfile) -> bool {
    matches!(p, PermissionProfile::External { .. })
}

Try / catch

Err(PermissionIntersectionError::ExternalSandbox) => {
    // fail closed: keep the stricter profile unmodified; never weaken either side
}

Prevention

When it happens

Trigger: Calling intersect_effective_permission_profiles(authority, requested, cwd) where either argument is PermissionProfile::External { .. } - for example a session launched inside a host-managed sandbox (outer Seatbelt/landlock/container) combined with any other profile.

Common situations: Host applications embedding Codex within their own sandbox; nested sandboxing; attempts to further restrict an externally enforced session by intersection.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/bc5bdf0021898417. Report an issue: GitHub.