Bubblewrap/示例

来自 ArchWiki

dhcpcd

创建一个简单的 dhcpcd 沙盒

  • 确定可用的内核命名空间
$ ls /proc/self/ns 
cgroup  ipc  mnt  net  pid  uts
注意: 缺少 user 表示内核构建时使用了 CONFIG_USER_NS=n 或者用户命名空间受限。
  • 将整个主机的 / 目录以读写方式绑定到沙盒中的 /
  • 在沙盒中的 /dev 挂载一个新的 devtmpfs 文件系统
  • 创建新的 IPC控制组 命名空间
  • 创建一个新的 UTS 命名空间并将主机名设置为 dhcpcd
# /usr/bin/bwrap --bind / / --dev /dev --unshare-ipc --unshare-cgroup --unshare-uts --hostname dhcpcd /usr/bin/dhcpcd -q -b

Unbound

创建一个更精细和复杂的 Unbound 沙盒

  • 将系统 /usr 目录以只读方式绑定到沙盒中的 /usr
  • 在沙盒中创建从系统 /usr/lib 目录到 /lib64 的符号链接
  • 将系统 /etc 目录以只读方式绑定到沙盒中的 /etc
  • 在沙盒中创建空的 /var/run 目录
  • 在沙盒中的 /dev 挂载一个新的 devtmpfs 文件系统
  • 创建新的 IPC 和 PID 以及控制组命名空间
  • 创建一个新的 UTS 命名空间并将主机名设置为 unbound
# /usr/bin/bwrap --ro-bind /usr /usr --symlink usr/lib /lib64 --ro-bind /etc /etc --dir /var --dir /run --dev /dev --unshare-ipc --unshare-pid --unshare-cgroup --unshare-uts --hostname unbound /usr/bin/unbound -d
提示: 参阅 systemd#编辑提供的单元 以启用 systemd 单元文件(包括 unbound.service)的 bubblewrap 封装

MuPDF

此文章或章节的事实准确性存在争议。

原因: 转发 X11 套接字可能导致沙盒逃逸(在 Talk:Bubblewrap/Examples 中讨论)

bwrap 的强大功能和灵活性在使用 shell 包装器创建环境时得到最佳体现

  • 将主机 /usr/bin 目录以只读方式绑定到沙盒中的 /usr/bin
  • 将主机 /usr/lib 目录以只读方式绑定到沙盒中的 /usr/lib
  • 在沙盒中创建从系统 /usr/lib 目录到 /lib64 的符号链接
  • 在沙盒中创建一个覆盖 /usr/lib/gcctmpfs 文件系统
    • 这有效地将 /usr/lib/gcc 的内容列入黑名单,使其不会出现在沙盒中
  • 在沙盒中创建一个新的 tmpfs 文件系统作为 $HOME 目录
  • .Xauthority 文件和 Documents 目录以只读方式绑定到沙盒中
    • 这有效地将 .Xauthority 文件和 Documents 目录递归地列入白名单
  • 在沙盒中创建一个新的 tmpfs 文件系统作为 /tmp 目录
  • 通过将 X11 套接字以只读方式绑定到沙盒中,将其列入白名单
  • 克隆并为正在运行的内核支持的所有命名空间创建私有容器
    • 如果内核不支持非特权用户命名空间,则跳过其创建并继续
  • 不要将网络组件放入私有命名空间
    • 这允许网络访问以跟踪 URI 超链接
#!/bin/sh
#~/bwrap/mupdf.sh
(exec bwrap \
--ro-bind /usr/bin /usr/bin \
--ro-bind /usr/lib /usr/lib \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/gcc \
--tmpfs $HOME \
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--ro-bind $HOME/Documents $HOME/Documents \
--tmpfs /tmp \
--ro-bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 \
 --unshare-all \
--share-net \
/usr/bin/mupdf "$@")
提示: 执行 shell 包装器,用 /usr/bin/sh 替换现有可执行文件,以调试和验证沙盒的内容和文件系统结构。
$ bwrap \
--ro-bind /usr/bin /usr/bin \
--ro-bind /usr/lib /usr/lib \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/gcc \
--tmpfs $HOME \
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--ro-bind $HOME/Desktop $HOME/Desktop \
--tmpfs /tmp \
--ro-bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 \
--unshare-all \
--share-net \
 /usr/bin/sh
bash-4.4$ ls -AF
.Xauthority  Documents/

构建 bubblewrap 文件系统时要考虑的最重要的规则可能是命令按照它们出现的顺序执行。 来自上面的 MuPDF 示例

  • 创建一个 tmpfs 系统,然后绑定挂载 .Xauthority 文件和 Documents 目录
--tmpfs $HOME \
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--ro-bind $HOME/Documents $HOME/Documents \
bash-4.4$ ls -a
.  ..  .Xauthority  Desktop
  • 在绑定挂载 .Xauthority 之后创建了一个 tmpfs 文件系统并覆盖它,因此只有 Documents 目录在沙盒中可见
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--tmpfs $HOME \
--ro-bind $HOME/Desktop $HOME/Desktop \
bash-4.4$ ls -a
.  ..  Desktop

p7zip

尚未针对 已知漏洞 打补丁的应用程序是 bubblewrap 的首选

  • 将主机 /usr/bin/7za 可执行文件路径以只读方式绑定到沙盒
  • 在沙盒中创建从系统 /usr/lib 目录到 /lib64 的符号链接
  • 使用 tmpfs 覆盖将沙盒化的 /usr/lib/modules/usr/lib/systemd 内容列入黑名单
  • 在沙盒中的 /dev 挂载一个新的 devtmpfs 文件系统
  • 将主机 /sandbox 目录以读写方式绑定到沙盒中的 /sandbox 目录
    • 从 shell 包装器调用时,7za 将仅在主机 /sandbox 目录和/或其子目录中运行
  • 为应用程序及其进程创建新的 cgroup/IPC/网络/PID/UTS 命名空间
    • 如果内核不支持非特权用户命名空间,则跳过其创建并继续
    • 创建新的网络命名空间会阻止沙盒获取网络访问权限
  • 向沙盒添加自定义或任意 主机名,例如 p7zip
  • 取消设置 XAUTHORITY 环境变量 以隐藏 X11 连接 cookie 的位置
    • 7za 不需要连接到 X11 显示服务器即可正常运行
  • 启动新的终端会话以防止键盘输入逃逸沙盒
#!/bin/sh
#~/bwrap/pz7ip.sh
(exec bwrap \
--ro-bind /usr/bin/7za /usr/bin/7za \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/modules \
--tmpfs /usr/lib/systemd \
--dev /dev \
--bind /sandbox /sandbox \
--unshare-all \
--hostname p7zip \
--unsetenv XAUTHORITY \
--new-session \
/usr/bin/7za "$@")
注意: /usr/bin/sh/usr/bin/ls 必须位于可执行路径中,才能遍历和验证沙盒文件系统。
bwrap \
--ro-bind /usr/bin/7za /usr/bin/7za \
--ro-bind /usr/bin/ls /usr/bin/ls \
--ro-bind /usr/bin/sh /usr/bin/sh \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/modules \
--tmpfs /usr/lib/systemd \
--dev /dev \
--bind /sandbox /sandbox \
--unshare-all \
--hostname p7zip \
--unsetenv XAUTHORITY \
--new-session \
/usr/bin/sh
bash: no job control in this shell
bash-4.4$ ls -AF         
dev/  lib64@  usr/
bash-4.4$ ls -l /usr/lib/modules 
total 0
bash-4.4$ ls -l /usr/lib/systemd
total 0
bash-4.4$ ls -AF /dev
console  full  null  ptmx@  pts/  random  shm/  stderr@  stdin@  stdout@  tty  urandom  zero
bash-4.4$ ls -A /usr/bin
7za  ls  sh

Firefox

具有较大攻击面的面向网络的应用程序也是 bubblewrap 的理想候选者

  • 沙盒中包含 Transmission,用于通过 magnet 和 torrent 链接启动
  • 示例包装器支持在 GNOME (Wayland) 下的音频 (PulseAudio) 和打印 (CUPS/Avahi)
    • ~/.config/transmission/settings.json 中的路径应反映 --setenv HOME 变量
  • 使用完整路径是为了允许在不支持变量扩展的环境中进行键盘绑定。
  • 包含 WebRenderer 和硬件(加速)合成支持
 bwrap \
--symlink usr/lib /lib \
--symlink usr/lib64 /lib64 \
--symlink usr/bin /bin \
--symlink usr/bin /sbin \
--ro-bind /usr/lib /usr/lib \
--ro-bind /usr/lib64 /usr/lib64 \
--ro-bind /usr/bin /usr/bin \
--ro-bind /usr/lib/firefox /usr/lib/firefox \
--ro-bind /usr/share/applications /usr/share/applications \
--ro-bind /usr/share/gtk-3.0 /usr/share/gtk-3.0 \
--ro-bind /usr/share/fontconfig /usr/share/fontconfig \
--ro-bind /usr/share/icu /usr/share/icu \
--ro-bind /usr/share/drirc.d /usr/share/drirc.d \
--ro-bind /usr/share/fonts /usr/share/fonts \
--ro-bind /usr/share/glib-2.0 /usr/share/glib-2.0 \
--ro-bind /usr/share/glvnd /usr/share/glvnd \
--ro-bind /usr/share/icons /usr/share/icons \
--ro-bind /usr/share/libdrm /usr/share/libdrm \
--ro-bind /usr/share/mime /usr/share/mime \
--ro-bind /usr/share/X11/xkb /usr/share/X11/xkb \
--ro-bind /usr/share/icons /usr/share/icons \
--ro-bind /usr/share/mime /usr/share/mime \
--ro-bind /etc/fonts /etc/fonts \
--ro-bind /etc/resolv.conf /etc/resolv.conf \
--ro-bind /usr/share/ca-certificates /usr/share/ca-certificates \
--ro-bind /etc/ssl /etc/ssl \
--ro-bind /etc/ca-certificates /etc/ca-certificates \
--dir "$XDG_RUNTIME_DIR" \
--ro-bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse" \
--ro-bind "$XDG_RUNTIME_DIR/wayland-1" "$XDG_RUNTIME_DIR/wayland-1" \
--dev /dev \
--dev-bind /dev/dri /dev/dri \
--ro-bind /sys/dev/char /sys/dev/char \
--ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 \
--proc /proc \
--tmpfs /tmp \
--bind /home/example/.mozilla /home/example/.mozilla \
--bind /home/example/.config/transmission /home/example/.config/transmission \
--bind /home/example/Downloads /home/example/Downloads \
--setenv HOME /home/example \
--setenv GTK_THEME Adwaita:dark \
--setenv MOZ_ENABLE_WAYLAND 1 \
--setenv PATH /usr/bin \
--hostname RESTRICTED \
--unshare-all \
--share-net \
--die-with-parent \
--new-session \
/usr/bin/firefox

增强隐私

  • 可以通过删除特定条目来进一步限制
    • 删除以下条目以删除音频支持
--ro-bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse" \
  • /sandbox 表示用户定义的任意位置,用于保存所需的配置文件信息
$ cp -pR ~/.mozilla /sandbox/

该位置可以是网络共享、USB 挂载点或本地文件系统或 ramfs/tmpfs 位置

  • 设置 /home/r 以模糊实际的 /home/example
  • 设置新的用户 ID 和组 ID 值
注意: 确保选择的 UID 和 GID 不会与 /etc/passwd/etc/groups 中列出的现有值冲突。
bwrap \
....
--bind /sandbox/.mozilla /home/r/.mozilla \
--bind /sandbox/Downloads /home/r/Downloads \
...
--setenv HOME /home/r \
...
--uid 200 --gid 400 \
...
/usr/bin/firefox --no-remote --private-window

Chromium

一个简单的 chromium 沙盒,在 wayland 上并使用 pipewire

bwrap \
    --symlink usr/lib /lib \
    --symlink usr/lib64 /lib64 \
    --symlink usr/bin /bin \
    --symlink usr/bin /sbin \
    --ro-bind /usr/lib /usr/lib \
    --ro-bind /usr/lib64 /usr/lib64 \
    --ro-bind /usr/bin /usr/bin \
    --ro-bind /etc /etc \
    --ro-bind /usr/lib/chromium /usr/lib/chromium \
    --ro-bind /usr/share /usr/share \
    --dev /dev \
    --dev-bind /dev/dri /dev/dri \
    --proc /proc \
    --ro-bind /sys/dev/char /sys/dev/char \
    --ro-bind /sys/devices /sys/devices \
    --ro-bind /run/dbus /run/dbus \
    --dir "$XDG_RUNTIME_DIR" \
    --ro-bind "$XDG_RUNTIME_DIR/wayland-1" "$XDG_RUNTIME_DIR/wayland-1" \
    --ro-bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0" \
    --ro-bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse" \
    --tmpfs /tmp \
    --dir $HOME/.cache \
    --bind $HOME/.config/chromium $HOME/.config/chromium \
    --bind $HOME/Downloads $HOME/Downloads \
    /usr/bin/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland
警告: 如果您正在使用 linux-hardened 内核,由于 kernel.unprivileged_userns_clone sysctl 设置为 0,您将无法使用 bubblewrap 沙盒化 chromium。 您可以将其设置为 1,但是,不建议这样做 FS#36969

一种替代解决方案是让 chromium 使用 bubblewrap 创建的命名空间。 这可以通过 zypakAUR 实现,flatpak 也使用它在额外的命名空间内运行基于 electron 的应用程序。 演示如何将 zypak 与 chromium/electron 一起使用的示例代码可以在 这里 找到

  • PipeWire: --ro-bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0" \
    • 如果您不使用 pipewire,请随意删除此行
  • --bind $HOME/.config/chromium $HOME/.config/chromium \ 将您的 chromium 配置目录以可读写方式挂载到沙盒中
  • --bind $HOME/Downloads $HOME/Downloads \ 将您的 ~/Downloads 目录以可读写方式挂载到沙盒中
  • 此示例可以进一步改进以获得更好的隔离。

Skype for Linux

此文章或章节的事实准确性存在争议。

原因: 转发 X11 和/或 DBus 套接字可能导致沙盒逃逸(在 Talk:Bubblewrap/Examples 中讨论)

以下示例提供这些功能

  • env -i 确保所有环境变量都未设置。
  • 网络与主机共享 (--share-net),/etc/resolv.conf 被绑定挂载。
  • Xorg 访问:绑定 /tmp/.X11-unix/X0 套接字,设置 $DISPLAY
  • D-Bus:绑定 $XDG_RUNTIME_DIR/bus 套接字,设置 $DBUS_SESSION_BUS_ADDRESS
  • 音频:绑定 PulseAudio 套接字。
  • 视频:dev-bind /dev/video0 设备。

主机上要保留 Skype 配置文件的目录可以使用 $HOST_PROFILE_PATH 进行配置。

env -i bwrap \
    --ro-bind /usr /usr \
    --dir /home/r \
    --dir /tmp \
    --dir /var \
    --dir "$XDG_RUNTIME_DIR" \
    --proc /proc \
    --dev /dev \
    --symlink usr/lib /lib \
    --symlink usr/lib64 /lib64 \
    --symlink usr/bin /bin \
    --symlink usr/sbin /sbin \
    --symlink ../tmp /var/tmp \
    --bind "$HOST_PROFILE_PATH" /home/r/.config/skypeforlinux \
    --ro-bind /etc/resolv.conf /etc/resolv.conf \
    --ro-bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 \
    --ro-bind "$XDG_RUNTIME_DIR/bus" "$XDG_RUNTIME_DIR/bus" \
    --ro-bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse" \
    --dev-bind /dev/video0 /dev/video0 \
    --chdir / \
    --unshare-all \
    --share-net \
    --hostname RESTRICTED \
    --die-with-parent \
    --new-session \
    --setenv PATH /usr/bin \
    --setenv HOME /home/r \
    --setenv XDG_RUNTIME_DIR "$XDG_RUNTIME_DIR" \
    --setenv DISPLAY "$DISPLAY" \
    --setenv DBUS_SESSION_BUS_ADDRESS "unix:path=$XDG_RUNTIME_DIR/bus" \
    /usr/bin/skypeforlinux

Steam

此文章或章节的事实准确性存在争议。

原因: 转发 X11 和/或 DBus 套接字可能导致沙盒逃逸(在 Talk:Bubblewrap/Examples 中讨论)

一个简单的 Steam 沙盒

#!/usr/bin/bash
set -e

STEAM_HOME="$HOME/.local/share/steam_sandbox"
RUN_USER="$XDG_RUNTIME_DIR"

mkdir -p "$STEAM_HOME"

_bind() {
	_bind_arg=$1
	shift
	for _path in "$@"; do
		args+=("$_bind_arg" "$_path" "$_path")
	done
}

bind() {
	_bind --bind-try "$@"
}

robind() {
	_bind --ro-bind-try "$@"
}

devbind() {
	_bind --dev-bind-try "$@"
}

args=(
	--tmpfs /tmp
	--proc /proc
	--dev /dev
	--dir /etc
	--dir /var
	--dir "$RUN_USER"
	--bind "$STEAM_HOME" "$HOME"
	--dir "$HOME"
	--dir "$XDG_CONFIG_HOME"
	--dir "$XDG_CACHE_HOME"
	--dir "$XDG_DATA_HOME"
	--dir "$XDG_STATE_HOME"
	--symlink /usr/lib /lib
	--symlink /usr/lib /lib64
	--symlink /usr/bin /bin
	--symlink /usr/bin /sbin
	--symlink /run /var/run
	--setenv XAUTHORITY "$XAUTHORITY"
)

robind \
	/usr \
	/etc \
	/opt \
	/sys \
	/var/empty \
	/var/lib/alsa \
	/var/lib/dbus \
	"$RUN_USER/systemd/resolve"

devbind \
	/dev/dri \
	/dev/nvidia* \
	/dev/input \
	/dev/uinput

# steam
bind \
	"$XAUTHORITY" \
	"$HOME/.local/bin/proton" \
	"$HOME/.pki" \
	"$HOME/.steam" \
	"$HOME/.steampath" \
	"$HOME/.steampid" \
	"$HOME/Downloads" \
	"$RUN_USER"/.mutter-X* \
	"$RUN_USER"/ICE* \
	"$RUN_USER"/dbus* \
	"$RUN_USER"/gnome* \
	"$RUN_USER"/pipewire* \
	"$RUN_USER"/pulse* \
	"$RUN_USER"/wayland* \
	"$RUN_USER/at-spi" \
	"$RUN_USER/bus" \
	"$RUN_USER/dconf" \
	"$RUN_USER/systemd" \
	"$XDG_CACHE_HOME/mesa_shader_cache" \
	"$XDG_CACHE_HOME/nv" \
	"$XDG_CACHE_HOME/nvidia" \
	"$XDG_CACHE_HOME/radv_builtin_shaders64" \
	"$XDG_CONFIG_HOME/Epic" \
	"$XDG_CONFIG_HOME/Loop_Hero" \
	"$XDG_CONFIG_HOME/MangoHud" \
	"$XDG_CONFIG_HOME/ModTheSpire" \
	"$XDG_CONFIG_HOME/RogueLegacy" \
	"$XDG_CONFIG_HOME/RogueLegacyStorageContainer" \
	"$XDG_CONFIG_HOME/cef_user_data" \
	"$XDG_CONFIG_HOME/proton" \
	"$XDG_CONFIG_HOME/pulse" \
	"$XDG_CONFIG_HOME/unity3d" \
	"$XDG_DATA_HOME/3909/PapersPlease" \
	"$XDG_DATA_HOME/Colossal Order" \
	"$XDG_DATA_HOME/Dredmor" \
	"$XDG_DATA_HOME/FasterThanLight" \
	"$XDG_DATA_HOME/HotlineMiami" \
	"$XDG_DATA_HOME/IntoTheBreach" \
	"$XDG_DATA_HOME/Paradox Interactive" \
	"$XDG_DATA_HOME/PillarsOfEternity" \
	"$XDG_DATA_HOME/RogueLegacy" \
	"$XDG_DATA_HOME/RogueLegacyStorageContainer" \
	"$XDG_DATA_HOME/Steam" \
	"$XDG_DATA_HOME/SuperHexagon" \
	"$XDG_DATA_HOME/Terraria" \
	"$XDG_DATA_HOME/applications" \
	"$XDG_DATA_HOME/aspyr-media" \
	"$XDG_DATA_HOME/bohemiainteractive" \
	"$XDG_DATA_HOME/cdprojektred" \
	"$XDG_DATA_HOME/feral-interactive" \
	"$XDG_DATA_HOME/frictionalgames" \
	"$XDG_DATA_HOME/icons" \
	"$XDG_DATA_HOME/proton" \
	"$XDG_DATA_HOME/vpltd" \
	"$XDG_DATA_HOME/vulkan" \
	"/var/lib/bluetooth" \
	/run/systemd \
	/tmp/.ICE-unix \
	/tmp/.X11-unix 

exec bwrap "${args[@]}" /usr/lib/steam/steam "$@"

NPM, Node Version Manager (NVM), Maven Java

为了能够在项目根目录中运行 npm,您可以使用以下命令。

它与 Angular、Cypress 和 Maven Java 结合使用。 顶部包含 X11 和 wayland 是因为 Cypress 启动了一个基于 electron 的 GUI。

它允许完全文件访问从其运行的当前目录。 假设您在当前项目根目录中执行 npm install,其中 npm 需要写入 node_modulespackage.json 等。 还允许访问全局 npm 安装目录和 nvm (npm -g install ...)。 此外,带有 cypress 的 X11 也能够运行,甚至 wayland 应用程序。

注意: zsh、maven 等目录的绑定可能与您的设置不同。
bwrap_arguments=(
    # no zombies
    --die-with-parent

    # network required for dependencies
    --unshare-all
    --share-net

    # create environment for a properly running shell
    --tmpfs /
    --tmpfs /run
    --dir /tmp
    --dev /dev
    --proc /proc
    --ro-bind /bin /bin
    --ro-bind /sbin /sbin
    --ro-bind /usr /usr
    --ro-bind /etc /etc
    --ro-bind /lib /lib
    --ro-bind /lib64 /lib64
    --ro-bind /sys /sys
    --ro-bind /var /var

    # systemd-resolve for dns
    --ro-bind /run/systemd/resolve /run/systemd/resolve

    # git is used by npm to init repos, config necessary for email username
    --ro-bind $XDG_CONFIG_HOME/git/config $XDG_CONFIG_HOME/git/config

    # zsh has to look everywhere cool
    --ro-bind $XDG_CONFIG_HOME/zsh/.zshrc $XDG_CONFIG_HOME/zsh/.zshrc
    --ro-bind $XDG_CONFIG_HOME/zsh/.zshenv $XDG_CONFIG_HOME/zsh/.zshenv
    --ro-bind $HOME/.zshenv $HOME/.zshenv

    # Maven
    --ro-bind /opt/maven /opt/maven
    --ro-bind $HOME/.m2 $HOME/.m2

    # NPM
    --bind "$XDG_DATA_HOME/npm" "$XDG_DATA_HOME/npm"

    # cache is needed by many programs like npm, cypress, nvm, maven
    --bind "$XDG_CACHE_HOME" "$XDG_CACHE_HOME"

    # x11, needed for cypress
    --ro-bind "$XAUTHORITY" "$XAUTHORITY"

    # wayland, might be useful
    --ro-bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"

    # current dir is assumed to be project dir and full access is allowed
    --bind "$(pwd)" "$(pwd)"
)

# run bwrap with the arguments specified above and with the command provided by the user: zsh, npm install, etc
$ bwrap "${bwrap_arguments[@]}" "$@"