First of all, thank you very much for looking into this so carefully. I appreciate the attention this is getting.
I also want to apologize in case my earlier reproduction with a very large ignored file tree may have derailed the investigation a bit. I am still going to look into that scenario more closely, but after further testing I am no longer sure that the number of files is the main trigger. I was able to reproduce what looks like the same, or at least a very similar, behavior with a much smaller setup.
Updated minimal setup
devcontainer.json:
{
"name": "${localWorkspaceFolderBasename}-devcontainer",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu24.04@sha256:6e5abd134eb1c2b747927487c3d59590bcc17815d5d7b3afd494e1be5de0f6b4",
"privileged": true,
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind,consistency=cached",
"remoteUser": "vscode",
"updateRemoteUserUID": true,
"containerEnv": {
"SBX_DEBUG": "1"
}
}
.cursorignore:
# Ignore everything
**
# This exclusion appears necessary. Without it, sandbox creation fails when trying to read the .git folder. However, it also seems to allow the sandbox to read illegal-file.md.
!/*
illegal-file.md
illegal-file.md:
you may not read this
Observed behavior
With the .cursorignore shown above, there seems to be a difference between the terminal-command access path and Cursor’s internal tools:
- Accessing
illegal-file.md via a terminal command, for example cat illegal-file.md, succeeds inside the sandbox.
- Accessing the same file via Cursor’s internal Read tool does not succeed.
From my point of view, the internal Read tool behavior seems closer to what I would expect. Since illegal-file.md is explicitly ignored, I would not expect terminal commands running inside the sandbox to be able to read it either.
Full output of the terminal:
sandbox: starting sandbox application
sandbox: original UID=1000, GID=1000
sandbox: step 0/7: skipping pre-discovery (preflight mode)
sandbox: step 1-2/7: creating namespaces (network_isolated=true)
sandbox: newuidmap/newgidmap not found, using setgroups deny method
sandbox: creating namespaces (setgroups deny mode, network_isolated=true)
sandbox: writing uid_map: 0 1000 1
sandbox: writing gid_map: 0 1000 1
sandbox: switching to root in namespace (setresgid)
sandbox: switching to root in namespace (setresuid)
sandbox: step 2.5/7: setting up loopback interface
sandbox: step 3/7: remounting / as MS_PRIVATE
sandbox: step 4/7: applying mount denies
sandbox: applying device restrictions
sandbox: staged /dev/null
sandbox: staged /dev/zero
sandbox: staged /dev/full
sandbox: staged /dev/random
sandbox: staged /dev/urandom
sandbox: staged /dev/tty
sandbox: created minimal /dev (8 mounts)
sandbox: device restrictions applied, mounts=8
sandbox: socket isolation: hiding "/run" with empty tmpfs
sandbox: socket isolation: skipping "/var/run" (already mounted as "/run")
sandbox: socket directory isolation applied, mounts=1
sandbox: workspace suffix rules root="/workspaces/cursor-sandbox-behavior" applied=0 mounts_total=9 t=0ms
sandbox: file-suffix rules (pre-discovered) applied=0 mounts_total=9 t=0ms
sandbox: git hooks rules applied=0 mounts_total=9 t=0ms
sandbox: mount denies summary mounts_total=9 suffix_applied=0 file_suffix_applied=0 git_hooks_applied=0 symlink_targets_applied=0 glob_applied=0 total=1ms
sandbox: step 5/7: applying landlock
sandbox: landlock: required V3 access_rw=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate)
sandbox: landlock: file-only access_rw=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate)
sandbox: landlock: ruleset created successfully (V3 required)
sandbox: landlock: preparing rule for "/dev/null" (optional=true)
sandbox: landlock: "/dev/null" is_directory=false
sandbox: landlock: preparing rule for "/dev/zero" (optional=true)
sandbox: landlock: "/dev/zero" is_directory=false
sandbox: landlock: preparing rule for "/dev/random" (optional=true)
sandbox: landlock: "/dev/random" is_directory=false
sandbox: landlock: preparing rule for "/dev/urandom" (optional=true)
sandbox: landlock: "/dev/urandom" is_directory=false
sandbox: landlock: preparing rule for "/dev/shm" (optional=true)
sandbox: landlock: "/dev/shm" is_directory=true
sandbox: landlock: preparing rule for "/workspaces/cursor-sandbox-behavior" (optional=false)
sandbox: landlock: "/workspaces/cursor-sandbox-behavior" is_directory=true
sandbox: landlock: preparing rule for "/workspaces/cursor-sandbox-behavior" (optional=false)
sandbox: landlock: "/workspaces/cursor-sandbox-behavior" is_directory=true
sandbox: landlock: preparing rule for "/tmp" (optional=true)
sandbox: landlock: "/tmp" is_directory=true
sandbox: landlock: preparing rule for "/var/tmp" (optional=true)
sandbox: landlock: "/var/tmp" is_directory=true
sandbox: landlock: adding write-allow rule for "/dev/null" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/null"
sandbox: landlock: adding write-allow rule for "/dev/zero" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/zero"
sandbox: landlock: adding write-allow rule for "/dev/random" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/random"
sandbox: landlock: adding write-allow rule for "/dev/urandom" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/urandom"
sandbox: landlock: adding write-allow rule for "/dev/shm" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/dev/shm"
sandbox: landlock: adding write-allow rule for "/workspaces/cursor-sandbox-behavior" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/workspaces/cursor-sandbox-behavior"
sandbox: landlock: adding write-allow rule for "/workspaces/cursor-sandbox-behavior" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/workspaces/cursor-sandbox-behavior"
sandbox: landlock: adding write-allow rule for "/tmp" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/tmp"
sandbox: landlock: adding write-allow rule for "/var/tmp" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/var/tmp"
sandbox: landlock: calling restrict_self() to enforce rules
sandbox: landlock: restrict_self() returned status=RestrictionStatus { ruleset: FullyEnforced, no_new_privs: true, landlock: Available { effective_abi: V6, kernel_abi: None } }
sandbox: landlock: ruleset fully enforced (effective: Available { effective_abi: V6, kernel_abi: None })
sandbox: landlock: CURSOR_SANDBOX_LANDLOCK_STATUS=fully_enforced
sandbox: landlock: filesystem write restrictions are now ACTIVE
sandbox: landlock: writes allowed ONLY to paths added above
sandbox: step 5.5/7: applying seccomp dangerous syscall block
sandbox: step 6/7: applying seccomp network block
sandbox: step 6.5/7: dropping bypass capabilities
sandbox: successfully dropped capabilities
sandbox: step 7/7: changing to working directory "/workspaces/cursor-sandbox-behavior"
sandbox: sandbox application completed successfully
sandbox: starting sandbox application
sandbox: original UID=1000, GID=1000
sandbox: step 0/7: pre-discovering files (before namespace)
sandbox: pre-discovering files before namespace creation
sandbox: pre-discovery: scanning git-backed workspace root
sandbox: pre-discovery: scanning workspace root for git hooks
sandbox: pre-discovery: scanning "/workspaces/cursor-sandbox-behavior" for git hooks
sandbox: pre-discovery: computing glob deny actions
sandbox: pre-discovery: filtered ignore mapping from 2 to 1 git-backed roots
sandbox: compute_glob_deny_actions (walker): planned_total=30 hide_dir=0 ro_dir=3 hide_file=0 ro_file=0 allow_rw=27 t=8ms
sandbox: pre-discovery: allowlist_paths=6
sandbox: pre-discovery: computing read-only deny actions
sandbox: compute_glob_deny_actions (walker): planned_total=5 hide_dir=1 ro_dir=0 hide_file=4 ro_file=0 allow_rw=0 t=12ms
sandbox: pre-discovery complete: suffix_files=2 git_hooks=1 glob_actions=35 symlink_targets=0 t=37ms
sandbox: step 1-2/7: creating namespaces (network_isolated=true)
sandbox: newuidmap/newgidmap not found, using setgroups deny method
sandbox: creating namespaces (setgroups deny mode, network_isolated=true)
sandbox: writing uid_map: 0 1000 1
sandbox: writing gid_map: 0 1000 1
sandbox: switching to root in namespace (setresgid)
sandbox: switching to root in namespace (setresuid)
sandbox: step 2.5/7: setting up loopback interface
sandbox: step 3/7: remounting / as MS_PRIVATE
sandbox: step 4/7: applying mount denies
sandbox: applying device restrictions
sandbox: staged /dev/null
sandbox: staged /dev/zero
sandbox: staged /dev/full
sandbox: staged /dev/random
sandbox: staged /dev/urandom
sandbox: staged /dev/tty
sandbox: created minimal /dev (8 mounts)
sandbox: device restrictions applied, mounts=8
sandbox: socket isolation: hiding "/run" with empty tmpfs
sandbox: socket isolation: skipping "/var/run" (already mounted as "/run")
sandbox: socket directory isolation applied, mounts=1
sandbox: workspace suffix rules root="/workspaces/cursor-sandbox-behavior" applied=0 mounts_total=9 t=0ms
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.cursorignore": EPERM: Operation not permitted, trying mount_setattr
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.git/config": EPERM: Operation not permitted, trying mount_setattr
sandbox: file-suffix rules (pre-discovered) applied=2 mounts_total=11 t=0ms
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.git/hooks": EPERM: Operation not permitted, trying mount_setattr
sandbox: blocked git hooks dir: "/workspaces/cursor-sandbox-behavior/.git/hooks"
sandbox: git hooks rules applied=1 mounts_total=12 t=0ms
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.devcontainer": EPERM: Operation not permitted, trying mount_setattr
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.git": EPERM: Operation not permitted, trying mount_setattr
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/my-folder": EPERM: Operation not permitted, trying mount_setattr
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.cursorignore": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.cursorignore_2_single-file": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.DS_Store": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.cursorignore_1_empty": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/README.md": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.gitignore": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.devcontainer/.DS_Store": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.devcontainer/devcontainer.json": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/config": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/HEAD": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/description": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/my-folder/illegal-file.md": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/info/exclude": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/commit-msg.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/pre-rebase.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/sendemail-validate.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/pre-commit.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/applypatch-msg.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/fsmonitor-watchman.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/pre-receive.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/prepare-commit-msg.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/post-update.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/pre-merge-commit.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/pre-applypatch.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/pre-push.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/update.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RW failed for "/workspaces/cursor-sandbox-behavior/.git/hooks/push-to-checkout.sample": EPERM: Operation not permitted, trying mount_setattr clear RDONLY
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.cursorignore": EPERM: Operation not permitted, trying mount_setattr
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.git/hooks": EPERM: Operation not permitted, trying mount_setattr
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.git/config": EPERM: Operation not permitted, trying mount_setattr
sandbox: glob denies (pre-discovered) applied_total=35 hide_dir=0 ro_dir=4 hide_file=0 ro_file=4 allow_rw=27 mounts_total=47 t=0ms
sandbox: mount denies summary mounts_total=47 suffix_applied=0 file_suffix_applied=2 git_hooks_applied=1 symlink_targets_applied=0 glob_applied=35 total=0ms
sandbox: step 5/7: applying landlock
sandbox: landlock: required V3 access_rw=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate)
sandbox: landlock: file-only access_rw=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate)
sandbox: landlock: ruleset created successfully (V3 required)
sandbox: landlock: preparing rule for "/dev/null" (optional=true)
sandbox: landlock: "/dev/null" is_directory=false
sandbox: landlock: preparing rule for "/dev/zero" (optional=true)
sandbox: landlock: "/dev/zero" is_directory=false
sandbox: landlock: preparing rule for "/dev/random" (optional=true)
sandbox: landlock: "/dev/random" is_directory=false
sandbox: landlock: preparing rule for "/dev/urandom" (optional=true)
sandbox: landlock: "/dev/urandom" is_directory=false
sandbox: landlock: preparing rule for "/dev/shm" (optional=true)
sandbox: landlock: "/dev/shm" is_directory=true
sandbox: landlock: preparing rule for "/workspaces/cursor-sandbox-behavior" (optional=false)
sandbox: landlock: "/workspaces/cursor-sandbox-behavior" is_directory=true
sandbox: landlock: preparing rule for "/workspaces/cursor-sandbox-behavior" (optional=false)
sandbox: landlock: "/workspaces/cursor-sandbox-behavior" is_directory=true
sandbox: landlock: preparing rule for "/tmp" (optional=true)
sandbox: landlock: "/tmp" is_directory=true
sandbox: landlock: preparing rule for "/var/tmp" (optional=true)
sandbox: landlock: "/var/tmp" is_directory=true
sandbox: landlock: adding write-allow rule for "/dev/null" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/null"
sandbox: landlock: adding write-allow rule for "/dev/zero" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/zero"
sandbox: landlock: adding write-allow rule for "/dev/random" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/random"
sandbox: landlock: adding write-allow rule for "/dev/urandom" (is_dir=false, access=BitFlags<AccessFs>(0b100000000000010, WriteFile | Truncate))
sandbox: landlock: successfully added rule for "/dev/urandom"
sandbox: landlock: adding write-allow rule for "/dev/shm" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/dev/shm"
sandbox: landlock: adding write-allow rule for "/workspaces/cursor-sandbox-behavior" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/workspaces/cursor-sandbox-behavior"
sandbox: landlock: adding write-allow rule for "/workspaces/cursor-sandbox-behavior" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/workspaces/cursor-sandbox-behavior"
sandbox: landlock: adding write-allow rule for "/tmp" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/tmp"
sandbox: landlock: adding write-allow rule for "/var/tmp" (is_dir=true, access=BitFlags<AccessFs>(0b111111111110010, WriteFile | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate))
sandbox: landlock: successfully added rule for "/var/tmp"
sandbox: landlock: calling restrict_self() to enforce rules
sandbox: landlock: restrict_self() returned status=RestrictionStatus { ruleset: FullyEnforced, no_new_privs: true, landlock: Available { effective_abi: V6, kernel_abi: None } }
sandbox: landlock: ruleset fully enforced (effective: Available { effective_abi: V6, kernel_abi: None })
sandbox: landlock: CURSOR_SANDBOX_LANDLOCK_STATUS=fully_enforced
sandbox: landlock: filesystem write restrictions are now ACTIVE
sandbox: landlock: writes allowed ONLY to paths added above
sandbox: step 5.5/7: applying seccomp dangerous syscall block
sandbox: step 6/7: applying seccomp network block
sandbox: step 6.5/7: dropping bypass capabilities
sandbox: successfully dropped capabilities
sandbox: step 7/7: changing to working directory "/workspaces/cursor-sandbox-behavior"
sandbox: sandbox application completed successfully
you may not read this
Additional observation
If the .cursorignore only contains the global ignore rule plus the ignored file, the sandbox setup itself appears to fail because .git is also hidden.
For example, with this .cursorignore:
**
illegal-file.md
I get the following sandbox output:
sandbox: starting sandbox application
sandbox: original UID=1000, GID=1000
sandbox: step 0/7: skipping pre-discovery (preflight mode)
[omitted due: post is to long otherwise]
sandbox: successfully dropped capabilities
sandbox: step 7/7: changing to working directory "/workspaces/cursor-sandbox-behavior"
sandbox: sandbox application completed successfully
sandbox: starting sandbox application
sandbox: original UID=1000, GID=1000
sandbox: step 0/7: pre-discovering files (before namespace)
sandbox: pre-discovering files before namespace creation
sandbox: pre-discovery: scanning git-backed workspace root
sandbox: pre-discovery: scanning workspace root for git hooks
sandbox: pre-discovery: scanning "/workspaces/cursor-sandbox-behavior" for git hooks
sandbox: pre-discovery: computing glob deny actions
sandbox: pre-discovery: filtered ignore mapping from 2 to 1 git-backed roots
sandbox: compute_glob_deny_actions (walker): planned_total=9 hide_dir=2 ro_dir=0 hide_file=7 ro_file=0 allow_rw=0 t=11ms
sandbox: pre-discovery: allowlist_paths=6
sandbox: pre-discovery: computing read-only deny actions
sandbox: compute_glob_deny_actions (walker): planned_total=5 hide_dir=1 ro_dir=0 hide_file=4 ro_file=0 allow_rw=0 t=9ms
sandbox: pre-discovery complete: suffix_files=2 git_hooks=1 glob_actions=14 symlink_targets=0 t=41ms
sandbox: step 1-2/7: creating namespaces (network_isolated=true)
sandbox: newuidmap/newgidmap not found, using setgroups deny method
sandbox: creating namespaces (setgroups deny mode, network_isolated=true)
sandbox: writing uid_map: 0 1000 1
sandbox: writing gid_map: 0 1000 1
sandbox: switching to root in namespace (setresgid)
sandbox: switching to root in namespace (setresuid)
sandbox: step 2.5/7: setting up loopback interface
sandbox: step 3/7: remounting / as MS_PRIVATE
sandbox: step 4/7: applying mount denies
sandbox: applying device restrictions
sandbox: staged /dev/null
sandbox: staged /dev/zero
sandbox: staged /dev/full
sandbox: staged /dev/random
sandbox: staged /dev/urandom
sandbox: staged /dev/tty
sandbox: created minimal /dev (8 mounts)
sandbox: device restrictions applied, mounts=8
sandbox: socket isolation: hiding "/run" with empty tmpfs
sandbox: socket isolation: skipping "/var/run" (already mounted as "/run")
sandbox: socket directory isolation applied, mounts=1
sandbox: workspace suffix rules root="/workspaces/cursor-sandbox-behavior" applied=0 mounts_total=9 t=0ms
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.cursorignore": EPERM: Operation not permitted, trying mount_setattr
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.git/config": EPERM: Operation not permitted, trying mount_setattr
sandbox: file-suffix rules (pre-discovered) applied=2 mounts_total=11 t=0ms
sandbox: remount RO failed for "/workspaces/cursor-sandbox-behavior/.git/hooks": EPERM: Operation not permitted, trying mount_setattr
sandbox: blocked git hooks dir: "/workspaces/cursor-sandbox-behavior/.git/hooks"
sandbox: git hooks rules applied=1 mounts_total=12 t=0ms
sandbox: hiding directory with tmpfs "/workspaces/cursor-sandbox-behavior/.devcontainer"
sandbox: hiding directory with tmpfs "/workspaces/cursor-sandbox-behavior/.git"
sandbox: bind blackhole "/tmp/.everysphere_sbx_bh_5206/blackhole" -> "/workspaces/cursor-sandbox-behavior/README.md"
sandbox: bind blackhole "/tmp/.everysphere_sbx_bh_5206/blackhole" -> "/workspaces/cursor-sandbox-behavior/illegal-file.md"
sandbox: bind blackhole "/tmp/.everysphere_sbx_bh_5206/blackhole" -> "/workspaces/cursor-sandbox-behavior/.cursorignore"
sandbox: bind blackhole "/tmp/.everysphere_sbx_bh_5206/blackhole" -> "/workspaces/cursor-sandbox-behavior/.gitignore"
sandbox: bind blackhole "/tmp/.everysphere_sbx_bh_5206/blackhole" -> "/workspaces/cursor-sandbox-behavior/.cursorignore_2_single-file"
sandbox: bind blackhole "/tmp/.everysphere_sbx_bh_5206/blackhole" -> "/workspaces/cursor-sandbox-behavior/.DS_Store"
sandbox: bind blackhole "/tmp/.everysphere_sbx_bh_5206/blackhole" -> "/workspaces/cursor-sandbox-behavior/.cursorignore_1_empty"
sandbox: mount bind failed for "/workspaces/cursor-sandbox-behavior/.git/hooks": ENOENT: No such file or directory
sandbox: failed at step 4/7 (mount denies): IO error: Failed to mount "/workspaces/cursor-sandbox-behavior/.git/hooks" read-only: IO error: No such file or directory (os error 2)
Error: Failed to apply sandbox: IO error: Step 4/7 (mount denies) failed: IO error: Failed to mount "/workspaces/cursor-sandbox-behavior/.git/hooks" read-only: IO error: No such file or directory (os error 2)
My current interpretation
This now looks like two related issues to me:
- A broad
** ignore rule also hides .git, and that obviously to interfere with sandbox setup.
- Adding
!/* seems to make sandbox setup work again, but then terminal commands can read illegal-file.md, while Cursor’s internal Read tool still cannot. Even if illegal-file.md is moved inside a folder (my-folder/illegal-file.md), read access through the terminal succeeds while accessing using the internal tool fails as expected.
So the current question is probably less about the size of the ignored tree and more about how .cursorignore rules are interpreted differently by the sandbox setup, terminal commands, and internal tools.
Please let me know if there is a better way to structure this reproduction. I will also continue testing the original large-file-tree case separately, but this smaller setup seems more useful as a starting point.