Portable is the sandbox framework originally designed for WeChat Qt. It provides D-Bus filtering and filesystem isolation.

Creating a sandbox

Creating a portable sandbox is easy as it uses the host system as a base. We’ll take Discord as an example.

Writing a config

We’ll start with the example config in the repository. Config parameters are explained as follows:

  • appID is the application ID of your sandbox, in the format of firstSection.secondSection.lastSection. Typically this should be the reversed domain of your package. For example Discord uses discord.com, we’ll suffix a .app because there’s no last section in this case. We’ll use com.discord.app
  • friendlyName is the name of your systemd user unit. It can only contain ASCII letters without any space. We’ll use “Discord”.
  • stateDirectory defines where the sandbox data lies in. It’s located under ~/.local/share/${stateDirectory}. We set it toDiscord_Data.
  • launchTarget is what the sandbox executes when it finished setting up the environment. This normally would be just the app executable. But in this case, we unset it and execute export launchTarget="/opt/discord/Discord --disable-setuid-sandbox --no-sandbox $@ --ozone-platform=wayland" in the bootstrap script instead due to the need of setting flags to Discord.
  • waylandOnly controls whether XAuth process and IM tweaks should happen. Set to false if you don’t understand what this means.
  • bindInputDevices determines whether /dev/input is exposed to the sandbox. It may be needed by games and other software using controllers.

Installing and starting up

By default configurations should be installed to /usr/lib/portable/info/appID/config. The bootstrap script should set _portableConfig to the application ID accordingly:

1
_portalConfig=/usr/lib/portable/info/appID/config portable

For Discord, this is

1
_portalConfig=/usr/lib/portable/info/com.discord.app/config portable

And we’re done. Sandbox is up and running