Flatpak – a look behind the portal

Flatpak allows sandboxed apps to interact with the rest of the system via portals. Portals are simply D-Bus services that are designed to be safe to expose to untrusted apps.

Principles

There are several principles that have guided the design of the existing portals.

 Keep the user in control

To achieve this, most portals  will show a dialog to let the user accept or deny the applications’ request. This is not a hard rule — in some cases, a dialog is just not practical.

Avoid yes/no questions

Direct questions about permissions tend to be dismissed without much thought, since they get in the way of the task at hand. Therefore, portals avoid this kind of question whenever possible and instead just let the user get on with the task.

For example, when an app is requesting to open a file on the host, we just present the user with a fille chooser. By selecting a file, the user implicitly grants the application access to the file. Or he can cancel the file selection and implicitly deny the applications’ request.

Don’t be annoying

Nothing is worse than having to answer the same question over and over. Portals make use of a database to record previous decisions and avoid asking repeatedly for the same thing.

Practice

The database used by portals is called the permission store. The permission store is organized in tables, with a table for each portal that needs one. It has a D-Bus api, but it is more convenient to explore it using the recently added flatpak commands:

flatpak permission-list
flatpak permission-list devices
flatpak permission-list desktop-used-apps video/webm

The first command will list all permissions in all tables, the second will show the content of the “devices” table, and the last one will show just the row for video/webm in the “desktop-used-apps” table.

There are also commands that deal with permissions on a per-application basis.

flatpak permission-show org.gnome.Epiphany
flatpak permission-reset org.gnome.Epiphany

The first command will show all the permissions that apply to the application, the second will remove all permissions for the application.

And more…

The most important table in the permission store is the “documents” table, where the documents portal stores information about host files that have been exported for applications. The documents portal makes the exported files available via a fuse filesystem at

/run/user/1000/doc

A useful subdirectory here is by-app, where the exported files are visible on a per-application bases (when setting up a sandbox, flatpak makes only this part of the document store available inside the sandbox).

It is instructive to browse this filesystem, but flatpak also has a dedicated set of commands for exploring the contents of the documents portal.

flatpak document-list
flatpak document-list org.gnome.Epiphany

The first command lists all exported files, the second shows only the files that are exported for an individual application.

flatpak document-info $HOME/example.pdf

This command shows information about a file that is exported in the document portal, such as which applications have access to it, and what they are allowed to do.

Lastly, there are document-export and document-unexport commands that allow to add or remove files from the document portal.

Summary

If you want to explore how portals work, or just need to double-check which files an app has access to, flatpak has tools that let you do so conveniently.

The Flatpak BoF at Guadec

Here is a quick summary of the Flatpak BoF that happened last week at Guadec.

1.0 approaching fast

We started by going over the list of outstanding 1.0 items. It is a very short list, and they should all be included in an upcoming 0.99.3 release.

  • Alex wants to add information about renaming to desktop files
  • Owen will hold his OCI appstream work for 1.1 at this point
  • James is interested in getting more information from snapd to portal backends, but this also does not need to block 1.0, and can be pulled into a 1.1 portals release
  • Matthias will review the open portal issues and make sure everything is in good shape for a 1.0 portal release

1.0 preparation

Alex will do a 0.99.3 release with all outstanding changes for 1.0 (Update: this release has happened by now). Matthias will work with  Allan and Bastien on the press release and other materials. Nick is very interested in having information about runtime availability, lifetime and stability easily available on the website for 1.0.

We agreed to remove the ‘beta’ label from the flathub website.

Post 1.0 plans

There was a suggestion that we should have an autostart portal. This request spawned a bigger discussion of application life-cycle control, background apps and services. We need to come up with a design for these intertwined topics before adding portals for it.

After 1.0, Alex wants to focus on tests and ci for a while. One idea in this area is to have a scriptable test app that can make portal requests.

Automatic migration on renames or EOL is on Endless’ wishlist.

Exporting repositories in local networks is a feature that Endless has, but it may end up upstream in ostree instead of flatpak.

Everybody agreed that GNOME Software should merge apps from different sources in a better way.

For runtimes, the GNOME release teams aims to have the GNOME runtime built using buildstream, on top of the freedesktop 1.8 runtime. This may or may not happen in time for GNOME 3.30.

Flatpak, making contribution easy

One vision that i’ve talked abut in the past is that moving to flatpak could make it much easier to contribute to applications.

Fast-forward 3 years, and the vision is (almost) here!

Every application on flathub has a Sources extension that you can install just like anything else from a flatpak repo:

flatpak install flathub org.seul.pingus.Sources

This extension contains a flatpak manifest which lists the exact revisions of all the sources that went into the build. This lets you reproduce the build — if you can find the manifest!

Assuming you install the sources per-user, the manifest is here (using org.seul.pingus as an example):

$HOME/.local/share/flatpak/runtime/org.seul.pingus.Sources/x86_64/stable/active/files/manifest/org.seul.pingus.json

And you can build it like this:

flatpak-builder build org.seul.pingus.json

I said the vision is almost, but not quite there. Here is why: gnome-builder also has a way to kickstart a project from a manifest:

gnome-builder --manifest org.seul.pingus.json

But sadly, this currently crashes. I filed an issue for it, and it will hopefully work very soon. Next step, flip-to-hack !

Flatpak in detail, part 3

The previous in this series looked at runtimes and filesystem organization. Here, we’ll take a look at the flatpak sandbox and explore how the world looks to a running flatpak app.

The sandbox, a view from the inside

Flatpak uses container technologies to set up a sandbox for the apps it runs. The name container brings to mind an image of a vessel with solid walls, which is a bit misleading.

In reality, a container is just a plain old process which talks directly to the kernel and other processes on the system. It is the job of the container management system, in this case flatpak, to launch the process with reduced privileges to limit the harm it can do to the rest of the system. To do this, flatpak uses the same kernel features that tools like docker use: namespaces, cgroups, seccomp.

Processes

One namespace that is used by flatpak is the pid namespace, which hides processes outside the sandbox from the sandboxed app.  If you run ps inside the sandbox, you’ll see something like this:

$ ps
PID TTY TIME CMD
1 ? 00:00:00 bwrap
2 ? 00:00:00 sh
3 ? 00:00:00 ps

One thing you’ll notice is that the app itself (the sh process, in this case) ends up with a PID of 2. Just something to keep in mind when getting your app ready for running in a sandbox: PIDs can’t be used to identify the app to the rest of the system anymore. This has caused minor problems, e.g with the _NET_WM_PID property that some window managers look at to decide about window decorations.

Filesystems

Another namespace that flatpak makes extensive use of is the mount namespace. It is used to create a customized view of the filesystem for the sandboxed app.

Running mount inside the sandbox will show you all the details, but its a bit much to show here, so we’ll just stick to the most important parts:

  • /app – this is where the apps files are mounted. It is a typical Unix filesystem with /app/share, /app/bin/, /app/lib and so on. When building an app for flatpak packaging, it typically gets configured with –prefix=/app for this reason.
  • /usr – the runtime files are placed here.
  • /run/host/ – various parts of the host filesystem that are safe to expose are mounted here, for example fonts (in /run/host/fonts) and icons (in /run/host/share/icons).
  • /usr/share/runtime/locale/ – the Locale extension of the runtime is mounted here.
  • Other extensions are mounted in their pre-determined places.
  • $HOME/.var/app/$APPID is made available to the app as well. This is the place in the home directory where flatpaked apps can store persistent data. The XDG_DATA_HOME, XDG_CONFIG_HOME and XDG_CACHE_HOME environment variables are set up to point to subdirectories in this place, and respecting these variables is a good way for an app to just work in a flatpak.

D-Bus

A common way for Linux apps to communicate with services and apps in the user session is via D-Bus, and most flatpak sandboxes allow the app to talk on the session bus (it can be turned off with a setting in the metadata). But we can’t just let the app talk to any other process on the bus, that would be a big risk. Therefore, flatpak sets up a filtering proxy that only allows the app to talk to certain names (this is again set up in the metadata).

The exception to this are portals – these are D-Bus interfaces specifically designed to be safe to expose, and apps are always allowed to talk to them. Portals offer APIs for a number of common needs, such as

  • org.freedestkop.portal.FileChooser  – Open a file
  • org.freedesktop.portal.OpenUri – Show a file in an app
  • org.freedesktop.portal.Print – Print a file
  • org.freedesktop.portal.Notification – Show a notification

Most of the time, portals will present a dialog to keep the user in control of what system access the sandboxed apps gets.

Toolkits like GTK+ can transparently use portals in some cases when they detect that the app is inside a sandbox, which greatly reduces the effort in using portals.

Metadata

But how does GTK+ find out that is being used inside a sandbox?

It looks for a file called .flatpak-info which flatpak places in the filesystem root of every sandbox. This file is not just a marker, it contains some useful information about the details of the sandbox setup, and is worth looking at. Some apps show information from here in their about dialog.

Summary

Flatpak sets up a customized sandbox for the apps it runs. It tries hard to preserve an environment that typical Linux desktop apps expect, including XDG locations and the session bus.