AppArmor cursor-sandbox profile incomplete on Linux — sandbox does not work correctly (missing network, signal, userns)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

On Linux systems with AppArmor enabled, the bundled /etc/apparmor.d/cursor-sandbox profile is incomplete. The current configuration is not enough for the sandbox to work correctly inside Cursor.

What’s wrong with the profile:

  1. Missing network rules — The profile does not allow network access. The sandbox needs it for language servers (LSP), extensions, and updates. Rules to add: network unix, and network inet stream, (for both cursor_sandbox and cursor_sandbox_remote).

  2. Missing signal rules — Processes inside the sandbox cannot send/receive signals to each other, which can break process coordination and clean shutdown. Rules to add: signal send peer=cursor_sandbox, and signal receive peer=cursor_sandbox,.

  3. userns commented out — The profile ships with userns commented and a note “Uncomment this on AppArmor 4.0”. On systems with AppArmor 4.0+, the sandbox needs user namespaces; leaving it commented causes failures. It should be uncommented so the profile works on AppArmor 4.0+.

  4. cursor_sandbox_remote binary name — The remote profile only matches the binary name cursorsandbox. In some setups the binary is named cursor-sandbox (with a hyphen). The profile should cover both, e.g. /home/*/.cursor-server/bin/*/*/resources/helpers/{cursor-sandbox,cursorsandbox}.

Result: sandbox errors, no network for language servers/extensions, and process coordination issues until the profile is manually updated.

Steps to Reproduce

  1. Install Cursor on a Linux system with AppArmor enabled (e.g. Ubuntu 24.04) using the .deb package.
  2. Ensure /etc/apparmor.d/cursor-sandbox is the one installed/updated by the Cursor .deb (default after install).
  3. Launch Cursor and use features that rely on the sandbox (e.g. agent/terminal, language servers, extensions that run in the sandbox).
  4. Observe: sandbox failures, missing network for LSP/extensions, or process coordination issues.

Expected Behavior

The sandbox should work correctly without manual edits: language servers and extensions should have network access, processes inside the sandbox should be able to coordinate via signals, and user namespaces should work on AppArmor 4.0+. The profile shipped with Cursor should include the rules above so no workaround is needed.

Operating System

Linux

Version Information

Version: 2.6.11
VSCode Version: 1.105.1
Commit: 8c95649f251a168cc4bb34c89531fae7db4bd990
Date: 2026-03-03T18:57:48.001Z
Build Type: Stable
Release Track: Default
Electron: 39.6.0
Chromium: 142.0.7444.265
Node.js: 22.22.0
V8: 14.2.231.22-electron.0
OS: Linux x64 6.17.0-14-generic

Additional Information

Example workaround (what I had to do on Ubuntu 24.04 until the profile is fixed):

  1. Back up the current profile (the one written by the Cursor .deb installer):

    sudo cp /etc/apparmor.d/cursor-sandbox /etc/apparmor.d/cursor-sandbox.bak
    
  2. Compare cursor-sandbox.bak with cursor-sandbox after any Cursor install/update to see what the installer changed. The installer’s version is missing the rules above; the .bak can hold your corrected version for comparison or restore.

  3. Apply the complete profile (e.g. save the suggested profile below as cursor-sandbox-merged and run):

    sudo cp /path/to/cursor-sandbox-merged /etc/apparmor.d/cursor-sandbox
    sudo cp /path/to/cursor-sandbox-merged /etc/apparmor.d/cursor-sandbox.bak
    sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox
    
  4. Make the file immutable so the Cursor .deb installer does not overwrite the fix on the next run:

    sudo chattr +i /etc/apparmor.d/cursor-sandbox
    

    To remove immutability later: sudo chattr -i /etc/apparmor.d/cursor-sandbox

Suggested full profile (to ship in future Cursor versions):

profile cursor_sandbox /usr/share/cursor/resources/app/resources/helpers/cursorsandbox {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  userns,

  mount,
  remount,
  umount,

  # Allow binary execution and mapping
  /usr/share/cursor/resources/app/resources/helpers/cursorsandbox mr,
  network unix,
  network inet stream,
  signal send peer=cursor_sandbox,
  signal receive peer=cursor_sandbox,
}

profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/{cursor-sandbox,cursorsandbox} {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  userns,

  mount,
  remount,
  umount,

  # Allow binary execution and mapping
  /home/*/.cursor-server/bin/*/*/resources/helpers/{cursor-sandbox,cursorsandbox} mr,
  network unix,
  network inet stream,
  signal send peer=cursor_sandbox,
  signal receive peer=cursor_sandbox,
}

Request: Include the above rules (network, signal, userns, and dual binary name for remote) in the official cursor-sandbox AppArmor profile shipped with Cursor, so the sandbox works correctly on Linux with AppArmor enabled. Thanks for considering this for future releases.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Two additional blockers on Ubuntu 24.04 (kernel 6.14, AppArmor 4.0) that aren’t covered above. Even with network, signal, and userns fixed as described, the sandbox still won’t start without addressing these.

1. Missing dac_override capability

The suggested profile lists sys_admin, net_admin, chown, setuid, setgid, setpcap — but newuidmap and newgidmap also need dac_override to write to /proc/[pid]/uid_map and /proc/[pid]/gid_map. Without it, UID/GID mapping fails and the namespace can’t be set up. This shows up in dmesg as:

apparmor="DENIED" operation="capable" class="cap" profile="cursor_sandbox"
  comm="newuidmap" capability=1 capname="dac_override"

Adding capability dac_override, to the profile fixes it. Or use blanket capability, — the profile already grants file, and /** ix, so selective capability restrictions don’t meaningfully reduce the attack surface.

2. No AppArmor profile for the main Cursor binary (unprivileged_userns)

This is a separate failure mode from the cursor_sandbox profile issues. Ubuntu 24.04 ships a system-wide unprivileged_userns AppArmor profile (/etc/apparmor.d/unprivileged_userns) that restricts user namespace creation. When an unconfined process creates a user namespace, it transitions to this profile, which denies sys_admin.

The cursor_sandbox profile only covers the helper binary at /usr/share/cursor/resources/app/resources/helpers/cursorsandbox. The main Electron binary at /usr/share/cursor/cursor has no profile — it runs unconfined and gets caught by unprivileged_userns:

apparmor="DENIED" operation="capable" class="cap" profile="unprivileged_userns"
  comm="cursor" capability=21 capname="sys_admin"

Neither the cursor .deb nor the cursor-sandbox-apparmor companion package installs a profile for this binary. The fix is to create /etc/apparmor.d/cursor:

abi <abi/4.0>,

profile cursor /usr/share/cursor/cursor flags=(unconfined) {
  userns,
}

This is the same pattern Docker Desktop uses on Ubuntu. It prevents the transition to unprivileged_userns without changing what Cursor can otherwise do — it was already running unconfined.

Upgrade overwrite

As a note for anyone who gets this working: /etc/apparmor.d/cursor-sandbox is owned by the cursor package, so every .deb upgrade overwrites your patched profile. The upgrade doesn’t reload the profile afterward either, so the old (now incorrect) profile stays in kernel memory. Cursor then silently falls back to unsandboxed execution with no warning — as @fscm44xyz noted, a clear diagnostic on failure would be much better than silent fallback.

chattr +i on the file (as suggested above) prevents the overwrite. Otherwise, re-patch and reload after each upgrade:

sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox
sudo apparmor_parser -r /etc/apparmor.d/cursor

Hey, thanks for the detailed report, and @a2f3, great add-on about dac_override and the profile for the main binary.

This is a known issue affecting users on Ubuntu 24.04+ with AppArmor 4.0 and kernel 6.2+. A few forum threads with the same problem:

The team is aware. I shared your thread for prioritization since it has the most complete analysis and a concrete proposed profile. There is no ETA for a fix yet.

For now, your workaround with chattr +i is probably the best option for users who want to keep AppArmor enabled. For users who want a quick fix, disabling the user namespaces restriction also works:

sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

(but this is less secure)

I’ll post an update here if there’s any news.

Hi everyone, I wanted to share a workaround that solved the AppArmor issues with cursor_sandbox and cursor_sandbox_remote for me on Ubuntu 24.04.4 LTS (Kernel 6.17.0-14-generic) , especially the DENIED errors related to network, userns, and capability dac_override.

In addition to the fixes mentioned in other threads, I was running into the problem that Cursor would overwrite the profile every time I reinstalled or updated it. What worked reliably for me was keeping only the minimal fix in the main profile, moving the additional permissions into /etc/apparmor.d/local/, and using dpkg-divert so the profile isn’t replaced during updates.

sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=1

sudo cp -a /etc/apparmor.d/cursor-sandbox /etc/apparmor.d/cursor-sandbox.predivert.$(date +%F_%H%M%S)

sudo dpkg-divert --local --rename --add \
  --divert /etc/apparmor.d/cursor-sandbox.distrib \
  /etc/apparmor.d/cursor-sandbox

sudo mkdir -p /etc/apparmor.d/local

sudo tee /etc/apparmor.d/cursor-sandbox >/dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile cursor_sandbox /usr/share/cursor/resources/app/resources/helpers/cursorsandbox {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  mount,
  remount,
  umount,

  /usr/share/cursor/resources/app/resources/helpers/cursorsandbox mr,

  include if exists <local/cursor-sandbox>
}

profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  mount,
  remount,
  umount,

  /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox mr,

  include if exists <local/cursor-sandbox-remote>
}
EOF

sudo tee /etc/apparmor.d/local/cursor-sandbox >/dev/null <<'EOF'
capability dac_override,
userns,
network,
EOF

sudo tee /etc/apparmor.d/local/cursor-sandbox-remote >/dev/null <<'EOF'
capability dac_override,
userns,
network,
EOF

sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox
sudo systemctl reload apparmor 2>/dev/null || true

Hi,

I’ve updated my previous workaround into a cleaner and more robust script:

#!/usr/bin/env bash
set -Eeuo pipefail

umask 022

APPARMOR_DIR=/etc/apparmor.d
LOCAL_DIR="${APPARMOR_DIR}/local"
BACKUP_DIR=/root/apparmor-backups/cursor

MAIN_FILE="${APPARMOR_DIR}/cursor-sandbox"
REMOTE_FILE="${APPARMOR_DIR}/cursor-sandbox-remote"
SYSTEM_FILE="${APPARMOR_DIR}/cursor-system"

log() {
  printf '[%s] %s\n' "$(date +%F' '%T)" "$*"
}

die() {
  printf 'ERROR: %s\n' "$*" >&2
  exit 1
}

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || die "missing required command: $1"
}

ensure_root() {
  [[ ${EUID:-$(id -u)} -eq 0 ]] || die 'run this script as root (sudo)'
}

backup_if_exists() {
  local src=$1
  local base dst

  [[ -e "$src" ]] || return 0

  base=$(basename "$src")
  dst="${BACKUP_DIR}/${base}.orig"

  if [[ -e "$dst" ]]; then
    log "backup already exists: $dst"
    return 0
  fi

  install -d -m 0755 "$BACKUP_DIR"
  cp -a -- "$src" "$dst"
  log "backup created: $dst"
}

quarantine_legacy_shadow_files() {
  local f dst
  install -d -m 0755 "$BACKUP_DIR"

  for f in \
    "${APPARMOR_DIR}/cursor-sandbox.distrib" \
    "${APPARMOR_DIR}/cursor-sandbox-remote.distrib" \
    "${APPARMOR_DIR}/cursor-system.distrib" \
    "${APPARMOR_DIR}/cursor-sandbox.dpkg-dist" \
    "${APPARMOR_DIR}/cursor-sandbox-remote.dpkg-dist" \
    "${APPARMOR_DIR}/cursor-system.dpkg-dist"
  do
    [[ -e "$f" ]] || continue
    dst="${BACKUP_DIR}/$(basename "$f").moved-aside"
    mv -f -- "$f" "$dst"
    log "legacy file moved out of ${APPARMOR_DIR}: $f -> $dst"
  done
}

write_if_changed() {
  local target=$1
  local tmp
  tmp=$(mktemp)
  cat >"$tmp"

  if [[ -e "$target" ]] && cmp -s "$tmp" "$target"; then
    rm -f -- "$tmp"
    log "no changes in ${target}"
    return 0
  fi

  install -D -m 0644 -- "$tmp" "$target"
  rm -f -- "$tmp"
  log "updated ${target}"
}

load_profile() {
  local path=$1
  apparmor_parser -r -T "$path"
  log "profile loaded: $path"
}

verify_loaded_profile() {
  local profile=$1

  if [[ -r /sys/kernel/security/apparmor/profiles ]]; then
    grep -Eq "^${profile}[[:space:]]+\(" /sys/kernel/security/apparmor/profiles \
      || die "profile ${profile} is not loaded in /sys/kernel/security/apparmor/profiles"
    log "verified loaded profile: ${profile}"
    return 0
  fi

  if command -v aa-status >/dev/null 2>&1; then
    aa-status 2>/dev/null | grep -Fq "$profile" \
      || die "profile ${profile} is not listed in aa-status"
    log "verified loaded profile with aa-status: ${profile}"
    return 0
  fi

  log "warning: could not verify ${profile}; /sys/kernel/security/apparmor/profiles and aa-status are unavailable"
}

main() {
  ensure_root
  need_cmd sysctl
  need_cmd apparmor_parser
  need_cmd install
  need_cmd cmp
  need_cmd grep
  need_cmd mv
  need_cmd cp

  install -d -m 0755 "$APPARMOR_DIR" "$LOCAL_DIR" "$BACKUP_DIR"

  backup_if_exists "$MAIN_FILE"
  backup_if_exists "$REMOTE_FILE"
  backup_if_exists "$SYSTEM_FILE"
  backup_if_exists "${LOCAL_DIR}/cursor-sandbox"
  backup_if_exists "${LOCAL_DIR}/cursor-sandbox-remote"
  backup_if_exists "${LOCAL_DIR}/cursor-sandbox-agent-cli"
  backup_if_exists "${LOCAL_DIR}/cursor-system"

  quarantine_legacy_shadow_files

  sysctl -w kernel.apparmor_restrict_unprivileged_userns=1 >/dev/null
  [[ "$(sysctl -n kernel.apparmor_restrict_unprivileged_userns)" == '1' ]] \
    || die 'kernel.apparmor_restrict_unprivileged_userns was not set to 1'
  log 'sysctl applied: kernel.apparmor_restrict_unprivileged_userns=1'

  write_if_changed "$SYSTEM_FILE" <<'EOF_SYSTEM'
abi <abi/4.0>,
include <tunables/global>

profile cursor_system /usr/share/cursor/cursor flags=(unconfined) {
  userns,

  include if exists <local/cursor-system>
}
EOF_SYSTEM

  write_if_changed "$MAIN_FILE" <<'EOF_MAIN'
abi <abi/4.0>,
include <tunables/global>

profile cursor_sandbox /usr/share/cursor/resources/app/resources/helpers/{cursor-sandbox,cursorsandbox} {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  mount,
  remount,
  umount,

  /usr/share/cursor/resources/app/resources/helpers/{cursor-sandbox,cursorsandbox} mr,

  include if exists <local/cursor-sandbox>
}
EOF_MAIN

  write_if_changed "$REMOTE_FILE" <<'EOF_REMOTE'
abi <abi/4.0>,
include <tunables/global>

profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/{cursor-sandbox,cursorsandbox} {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  mount,
  remount,
  umount,

  /home/*/.cursor-server/bin/*/*/resources/helpers/{cursor-sandbox,cursorsandbox} mr,

  include if exists <local/cursor-sandbox-remote>
}

profile cursor_sandbox_agent_cli /home/*/.local/share/cursor-agent/versions/*/{cursor-sandbox,cursorsandbox} {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  mount,
  remount,
  umount,

  /home/*/.local/share/cursor-agent/versions/*/{cursor-sandbox,cursorsandbox} mr,

  include if exists <local/cursor-sandbox-agent-cli>
}
EOF_REMOTE

  write_if_changed "${LOCAL_DIR}/cursor-system" <<'EOF_LOCAL_SYSTEM'
signal (send, receive) peer=cursor_sandbox,
signal (send, receive) peer=cursor_sandbox_remote,
signal (send, receive) peer=cursor_sandbox_agent_cli,
EOF_LOCAL_SYSTEM

  write_if_changed "${LOCAL_DIR}/cursor-sandbox" <<'EOF_LOCAL_MAIN'
capability dac_override,
userns,
network unix stream,
network unix dgram,
network netlink raw,
network netlink dgram,
signal (send, receive) peer=cursor_system,
EOF_LOCAL_MAIN

  write_if_changed "${LOCAL_DIR}/cursor-sandbox-remote" <<'EOF_LOCAL_REMOTE'
capability dac_override,
userns,
network unix stream,
network unix dgram,
network netlink raw,
network netlink dgram,
signal (send, receive) peer=cursor_system,
EOF_LOCAL_REMOTE

  write_if_changed "${LOCAL_DIR}/cursor-sandbox-agent-cli" <<'EOF_LOCAL_AGENT'
capability dac_override,
userns,
network unix stream,
network unix dgram,
network netlink raw,
network netlink dgram,
signal (send, receive) peer=cursor_system,
EOF_LOCAL_AGENT

  load_profile "$SYSTEM_FILE"
  load_profile "$MAIN_FILE"
  load_profile "$REMOTE_FILE"

  verify_loaded_profile cursor_system
  verify_loaded_profile cursor_sandbox
  verify_loaded_profile cursor_sandbox_remote
  verify_loaded_profile cursor_sandbox_agent_cli

  log 'Cursor AppArmor fix has been applied and validated.'
  log 'Close and reopen Cursor to test it.'
}

main "$@"

Hey everyone, quick update: the fix should already be out. Just run apt update or reinstall the Cursor package, and it should be fixed automatically.

I wonder that before updating do we need to move the previous chattr +isettting.

Yes, before updating you need to remove the immutable flag, otherwise apt won’t be able to overwrite the file with the new fixed profile:

sudo chattr -i /etc/apparmor.d/cursor-sandbox

After that, update as usual:

sudo apt update && sudo apt upgrade

The new package should install the fixed profile, so you don’t need to run chattr +i again.

I’m very curious: is it that your .deb package doesn’t distinguish between local and remote servers, or did you simply not consider this case at all? The matching path for the cursor-remote executable in your package has consistently been wrong. At least on my remote server, the correct path is /home/*/.cursor-server/cli/servers/*/server/resources/helpers/{cursor-sandbox,cursorsandbox}, yet after several updates, you still haven’t noticed this issue.

sudo mv /etc/apparmor.d/cursor* /root/apparmor-backups/cursor/
sudo dpkg -i cursor-sandbox-apparmor.deb
sudo dpkg -i cursor_2.6.21_amd64.deb

cat /etc/apparmor.d/cursor-sandbox.distrib

profile cursor_sandbox /usr/share/cursor/resources/app/resources/helpers/cursorsandbox {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  ## Uncomment this on AppArmor 4.0
  #userns,

  mount,
  remount,
  umount,

  /usr/share/cursor/resources/app/resources/helpers/cursorsandbox mr,
}

profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,

  ## Uncomment this on AppArmor 4.0
  #userns,

  mount,
  remount,
  umount,

  /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox mr,
}

cat /etc/apparmor.d/cursor-sandbox-remote.distrib

profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,
  network unix,
  network inet stream,
  network inet6 stream,
  network netlink raw,

  ## Uncomment this on AppArmor 4.0
  #userns,

  mount,
  remount,
  umount,

  /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox mr,
}

profile cursor_sandbox_agent_cli /home/*/.local/share/cursor-agent/versions/*/cursorsandbox {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,
  network unix,
  network inet stream,
  network inet6 stream,
  network netlink raw,

  ## Uncomment this on AppArmor 4.0
  #userns,

  mount,
  remount,
  umount,

  /home/*/.local/share/cursor-agent/versions/*/cursorsandbox mr,
}

sudo systemctl reload apparmor

sudo journalctl -xe | grep -i apparmor | grep cursor

Mar 25 07:00:07 60A1A37600 kernel: audit: type=1400 audit(1774432807.815:251): apparmor="DENIED" operation="create" class="net" info="failed af match" error=-13 profile="cursor_sandbox" pid=161256 comm="newuidmap" family="unix" sock_type="stream" protocol=0 requested="create" denied="create" addr=none
Mar 25 07:00:07 60A1A37600 kernel: audit: type=1400 audit(1774432807.815:252): apparmor="DENIED" operation="create" class="net" info="failed af match" error=-13 profile="cursor_sandbox" pid=161256 comm="newuidmap" family="unix" sock_type="stream" protocol=0 requested="create" denied="create" addr=none
Mar 25 07:00:07 60A1A37600 kernel: audit: type=1400 audit(1774432807.816:253): apparmor="DENIED" operation="capable" class="cap" profile="cursor_sandbox" pid=161256 comm="newuidmap" capability=1  capname="dac_override"
Mar 25 07:00:08 60A1A37600 kernel: audit: type=1400 audit(1774432808.822:254): apparmor="DENIED" operation="create" class="net" info="failed af match" error=-13 profile="cursor_sandbox" pid=162044 comm="newuidmap" family="unix" sock_type="stream" protocol=0 requested="create" denied="create" addr=none
Mar 25 07:00:08 60A1A37600 kernel: audit: type=1400 audit(1774432808.822:255): apparmor="DENIED" operation="create" class="net" info="failed af match" error=-13 profile="cursor_sandbox" pid=162044 comm="newuidmap" family="unix" sock_type="stream" protocol=0 requested="create" denied="create" addr=none
Mar 25 07:00:08 60A1A37600 kernel: audit: type=1400 audit(1774432808.824:256): apparmor="DENIED" operation="capable" class="cap" profile="cursor_sandbox" pid=162044 comm="newuidmap" capability=1  capname="dac_override"
Mar 25 07:00:08 60A1A37600 kernel: audit: type=1400 audit(1774432808.837:257): apparmor="DENIED" operation="create" class="net" info="failed af match" error=-13 profile="cursor_sandbox" pid=162066 comm="newuidmap" family="unix" sock_type="stream" protocol=0 requested="create" denied="create" addr=none
Mar 25 07:00:08 60A1A37600 kernel: audit: type=1400 audit(1774432808.837:258): apparmor="DENIED" operation="create" class="net" info="failed af match" error=-13 profile="cursor_sandbox" pid=162066 comm="newuidmap" family="unix" sock_type="stream" protocol=0 requested="create" denied="create" addr=none
Mar 25 07:00:08 60A1A37600 kernel: audit: type=1400 audit(1774432808.837:259): apparmor="DENIED" operation="capable" class="cap" profile="cursor_sandbox" pid=162066 comm="newuidmap" capability=1  capname="dac_override"

This isn’t working, what should I do? @deanrie

@Williamleejx - good catch about the path on the remote machine. The current profile only matches /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox, but some remote server setups use /home/*/.cursor-server/cli/servers/*/server/resources/helpers/. I passed this to the team.

@gcespedes - yep, the logs show the fix was only partial. The cursor-sandbox-remote profile got network rules in 2.6.21, but the local cursor-sandbox profile did not. It’s still missing network and dac_override, and userns is still commented out.

For now, the best option is to use your script from post #10 since it covers everything. Or if you want a quick manual fix, overwrite just the local profile:

sudo tee /etc/apparmor.d/cursor-sandbox > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile cursor_sandbox /usr/share/cursor/resources/app/resources/helpers/{cursor-sandbox,cursorsandbox} {
  file,
  /** ix,

  capability sys_admin,
  capability net_admin,
  capability chown,
  capability setuid,
  capability setgid,
  capability setpcap,
  capability dac_override,

  userns,

  network unix,
  network inet stream,
  network inet6 stream,
  network netlink raw,

  mount,
  remount,
  umount,

  /usr/share/cursor/resources/app/resources/helpers/{cursor-sandbox,cursorsandbox} mr,
}
EOF
sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox

I also passed both issues to the team, the incomplete local profile and the wrong remote path. No ETA yet, but your reports help us prioritize. I’ll update here when I have news.