New flatpak command line

Today I released version 0.6.13 of flatpak which has a lot of nice new features. One that I’d like to talk a bit about is the new command line argument format.

The flatpak command line was always a bit low-level and hard to use. Partly this was because of lack of focus on this, and partly due to the fact that the expected UI for flatpak for most people would be a graphical user interface like gnome-software. However, with this new release this changed, and flatpak is now much nicer to use from the commandline.

So, what is new?

Flatpakrepo files

Before you can really use flatpak you have to configure it so it can find the applications and runtimes. This means setting up one or more remotes. Historically you did this by manually specifying all the options for the remote as arguments to the flatpak remote-add command. To make this easier we added a file format (.flatpakrepo) to describe a remote, and made it easy to use it.

The new canonical example to configure the gnome stable repositories is:

$ flatpak remote-add --from gnome \
$ flatpak remote-add --from gnome-apps \

Alternatively you can just click on the above links and they should open in gnome-software (if you have new enough versions installed).

Multiple arguments to install/update/uninstall

Another weakness of the command line has been that commands like install, uninstall and update only accepted one application name argument (and optionally a branch name). This made it hard to install multiple apps in one go, and the separate branch name made it hard to cut-and-paste from output of e.g. flatpak list.

Instead of the separate branch name all the commands now take multiple “partial refs” as arguments. These are partial versions of the OSTree ref format that flatpak uses internally. So, for an internal reference like app/org.gnome.gedit/x86_64/stable, one can now specify one of these:


And flatpak will automatically fill in the missing part in a natural way, and give a detailed error if you need to specify more details:

$ flatpak install gnome org.gnome.Platform
error: Multiple branches available for org.gnome.Platform, you must specify one of: org.gnome.Platform//3.20, org.gnome.Platform//3.22, org.gnome.Platform//3.16, org.gnome.Platform//3.18

Automatic dependencies

The other problem with the CLI has been that it is not aware of runtime dependencies. To run an app you generally had to know what runtime it used and install that yourself. The idea here was that the commandline should be simple, non-interactive and safe. If you instead use the graphical frontend it will install dependencies interactively so you can control where things get installed from.

However, this just made the CLI a pain to use, and you could easily end up in situations where things didn’t work. For instance, if you updated gedit from 3.20 to 3.22 it suddenly depended on a new runtime version, and if you weren’t aware of this it probably just stopped working.

Of course, we still can’t just install dependencies from wherever we find them, because that would be a security issue (any configured remote can supply a runtime for any applications). So, the solution here is for flatpak to become interactive:

$ flatpak update org.gnome.gedit
Looking for updates...
Required runtime for org.gnome.gedit/x86_64/stable (org.gnome.Platform/x86_64/3.22) is not installed, searching...
Found in remote gnome, do you want to install it? [y/n]: y
Installing: org.gnome.Platform/x86_64/3.22 from gnome
Installing: org.gnome.Platform.Locale/x86_64/3.22 from gnome
Updating: org.gnome.gedit/x86_64/stable from gnome-apps
Updating: org.gnome.gedit.Locale/x86_64/stable from gnome-apps

If you have remotes you never want to install dependencies from, you can install them with --no-use-for-deps, and they will not be used. Flatpakrepo files for app-only repositories should set NoDeps=true.

Note that this is not a package-system-like dependency solver that can solve sudoku. It is still a very simple two-way split.

Flatpakref files

The primary way Flatpak is meant to be used is that you configure a few remotes that has most of the applications that you use, then you install from these either on the command line, or via a graphical installer. However, sometimes it is nice to have a single link you can put on a website to install your application. Flatpak now supports that via .flatpakref files. These are very similar to flatpakrepo files, in that they describe a repository, but they additionally contain a particular application in that repository which will be installed.

Such files can be installed by just clicking on them in your web-browser (which will open them for installation in gnome-software) or on the command line:

flatpak install --from

This will try to install the required runtime, so you first need to add the remote with the runtimes.

Launching runtimes

During development and testing it is often common to launch commands in a sandbox to experiment with how the runtime works. This was always possible by running a custom command in an application that used the runtime, like so:

$ flatpak run --command=sh org.gnome.gedit
sh-4.3$ ls /app
bin lib libexec manifest.json share

You can even specify a custom runtime with --runtime. However, there really should be no need to have an application installed to do this, so the new version allows you to directly run a runtime:

$ flatpak run org.gnome.Platform//3.22
sh-4.3$ ls /app

Using bubblewrap in xdg-app

At the core of xdg-app is a small helper binary that uses Linux features like namespaces to set up sandbox for the application. The main difference between this helper and a full-blown container system is that it runs entirely as the user. It does not require root privileges, and can never allow you to get access to things you would not otherwise have.

This is obviously very useful for desktop application sandboxing, but has all sort of other uses. For instance, you can sandbox your builds to avoid them being polluted from the host, or you can run a nonprivileged service with even less privileges.

The current helper was a bit too tied to xdg-app, so as part of Project Atomic we decided to create a separate project based on this code, but more generic and minimal. Thus Bubblewrap was born.

Bubblewrap is a wrapper tool, similar to sudo or chroot. You pass it an executable and its argument on the command line. However, the executable is run in a custom namespace, which starts out completely empty, with just a tmpfs mounted as the root, and nothing else. You can then use commandline arguments to build up the sandbox.

For example, a very simple use of bubblewrap to run a binary with access to everything, but readonly:

$ bwrap --ro-bind / / touch ~/foo
touch: cannot touch ‘/home/alex/foo’: Read-only file system

Or you can use bubblewrap as an regular chroot that doesn’t require you to be root to use it:

$ bwrap --bind /some/chroot / /bin/sh

Here is a more complicated example with a read-only host /usr (and no other host files), a private pid namespace, and no network access:

$ bwrap --ro-bind /usr /usr \
      --dir /tmp \
      --proc /proc \
      --dev /dev \
      --ro-bind /etc/resolv.conf /etc/resolv.conf \
      --symlink usr/lib /lib \
      --symlink usr/lib64 /lib64 \
      --symlink usr/bin /bin \
      --chdir / \
      --unshare-pid \
      --unshare-net \

See the bubblewrap manpage for more details.

Today I changed xdg-app to use bubblewrap instead of its own helper, which means if you start an app with xdg-app it is using bubblewrap underneath.

For now it is using its own copy of the code (using git submodules), but as bubblewrap starts to get deployed more widely we can start using the system installed version of it.

xdg-app builds for gnome 3.20 are out

Finally there are now stable builds of the Gnome 3.20 runtime. I updated the Runtime wiki page  with details on how to install it.

This has been a long time coming, because this new runtime as well as the runtime that it is based is built in a new way. It used to be built with a custom script, but now it uses the new xdg-app-builder tool. This makes it a lot cleaner and easier to maintain.

Also worth mentioning is the base 1.4 runtime. This has been updated, modernized and cleaned up to make a great base both for applications that don’t need a lot of runtime support (such as games) and as a base for other runtimes. In fact, Alexei is using this as the base for the KDE runtimes too.

I have also set up a gnome-apps repository with stable builds of some Gnome 3.20 applications. This lets you test Gnome 3.20 applications on older distributions.

Documentation on how to install these can be found on Runtime wiki page , but as a teaser i give you the commands to test gedit if you have zero xdg-app setup:

$ wget
$ xdg-app remote-add --user --gpg-import=gnome-sdk.gpg gnome
$ xdg-app --user install gnome org.gnome.Platform 3.20
$ xdg-app --user remote-add --gpg-key=gnome-sdk.gpg gnome-apps
$ xdg-app --user install gnome-apps org.gnome.gedit stable
$ xdg-app run org.gnome.gedit

These runtimes will be a great base if you want to experiment with building xdg-apps, and going forward we will start looking at integrating xdg-app better into the Gnome development and release schedule.

Also, Endless Mobile are sponsoring Gnome with ARM hardware and people working on that, so I hope we can soon have official Gnome runtimes for ARM too.

xdg-app 0.5.0 released

When I set out to create xdg-app I had two goals:

  • Make it possible for 3rd parties to create and distribute applications that works on multiple distributions.
  • Run applications with as little access as possible to the host. (For example access to the network or the users files.)

Yesterday I released version 0.5.0 of xdg-app, and which I now finally consider feature complete for the first of these goals. It now has tooling that makes it easy to build apps, it has multiple graphical frontends, and it is now pretty robust and featureful.

0.5.0 is already built in Fedora 23, and is available for other distributions here.

No software is ever finished obviously, so I will continue working on xdg-app. However, going forward the majority of my work will now be focusing on the sandboxing and portal aspects of xdg-app.

Building an xdg-app – part 5

In the previous parts (1,2,3,4) we created various applications and tested them locally. Now we will look into how this application can be distributed to your users.

First we need to talk a bit about OSTree. This is the core distribution and installation mechanism of xdg-app. OSTree is similar to git, but has been designed to handle trees of large binaries. Just like git it has the concept of repositories, commits and branches (refs) . Branches are names which points to a commit id, and an application stored in a repository is such a branch.

On your machine there is a local OSTree repository which has a bunch of “remotes” configured. When you install or update an application from one on these remotes, what happens is that we ostree pull the branch from the remote, then do a local checkout of the branch (with hard links back to the repository files, so this is cheap).

The OSTree repositories created by xdg-app build-export are of a type (called archive-z2) that are meant to be served by a dumb webserver. So, to distribute your application, all you have to do is copy the repository to a webserver and give the url to your users.

There are however some extra details you have to be aware off .

First of all, the format of the archive-z2 repositories is one file per file in the app. This means a pull operation will do a lot of http requests. Since new requests are slow, make sure you enable support for HTTP keep-alive in your webserver.

OSTree also supports something called static deltas. These are single files in the repo that contains all the data needed to go between two revisions (or from nothing to a revision). Creating such deltas will take a bit more space, but will make downloads much faster.

xdg-app has the build-update-repo command that is very useful to manage repositories. Starting at version 0.4.13 it supports --generate-static-deltas to generate the deltas. but it also has several other features that are useful. For instance, you can use:

xdg-app build-update-repo --title="Nice name" repo

To set a user readable name for the repository, which will be used by default in the UI when users see this repository.

It also lets you prune (--prune) unused objects and deltas from the repository, and even remove older revisions from your repository (--prune-depth) which is useful for things like automatic nightly build repositories.

Another thing build-update-repo does is appstream extraction. It scans all the branches in the repository and looks for an AppStream xml file. For instance, the dictionary app from part 3 contains such a file in files/share/app-info/xmls/org.gnome.Dictionary.xml.gz. All these files plus the icons they reference are collected and commited into a repo-wide appstream branch. xdg-app keeps a local copy of this branch for each remote, which you can manually update with:

xdg-app --user update --appstream nightly

This is used by graphical installation tools such as gnome-software, so having appstream data for your applications is important.

Note: xdg-app-builder automatically runs the appstream-compose command after the build. This will collect information from appdata files and desktop files and create the right xml.gz and icon files. This is where the xml in gnome-dictionary came from.

Another important part about app distribution is gpg signatures. By default OSTree refuses to pull anything from a remote repository that is not signed. This is only allowed if you use --no-gpg-verify when you add the remote (or you can change it with xdg-app remote-modify).

In OSTree, signatures are on each commit and on the summary file that lists all the branches in the repositories. These objects are created by the build-update-repo, and build-export commands, as well as indirectly by xdg-app-builder. So, when you call these, you should pass in the gpg keys to sign with, and optionally the gpg home directory to use. For example:

xdg-app build-export --gpg-sign=KEYID --gpg-homedir=/some/dir appdir repo

That concludes this tutorial series, and you should now know enough to package and distribute your own applications.

Building an xdg-app – part 4

In part 1 we created a very small application. All it did was print to stdout. Such a program is very easy to sandbox. In fact, since we didn’t specify any permissions for it this application already runs in a very tight sandbox.

Here is what the sandbox does:

  • No access to any host files except the runtime, the app, and ~/.var/app/org.test.Hello,  and only the last of these  is writable.
  • /tmp is unique to the application instance.
  • setuid functionallity is disabled.
  • Processes are in a cgroup which they cannot get out of. This lets you know what application a process is running in, in an unfakable way. (This will be very important later for per-application preferences.)
  • No access to the network.
  • No access to any device nodes (apart from /dev/null, etc).
  • Can’t see any processes outside the sandbox.
  • A set of seccomp rules are loaded that limits what syscalls the app can do.  For instance, it can’t use nonstandard network socket types, or ptrace other processes.
  • Limited access to the session dbus instance, is only allowed  to own its own name on the bus and can’t talk to anyone else.
  • No access to host services like X, system dbus, or pulseaudio.

Of course, its very easy to secure a Hello world program, as it doesn’t need to do anything. There are designs (and experimental code) to allow applications to securely break out of the sandbox (using something called Portals). However, that is not stable for general use at this point. What is usable now though is punching minimal holes in the sandbox such that the applications can do what it needs.

We saw this already in part 2, where we used this command, granting X11 and network access:

xdg-app build-finish appdir2 --socket=x11 --share=network --command=gnome-dictionary

These arguments translate to these properties in the application metadata file:



As we gave no access to the filesystem in the above the resulting app can’t see your files. We can verify this with a command like:

$ xdg-app run --command=ls org.gnome.Dictionary ~/

The permissions in the metadata file are only the default values though. You can override these in different ways. First of all, xdg-app run takes the same command line arguments as build-finish, which can override permissions for that instance. For example, this will let it see your home directory:

$ xdg-app run --filesystem=home --command=ls org.gnome.Dictionary ~/
<homedir listing...>

You can also permanently override permissions for an application:

$ xdg-app --user override --filesystem=home org.gnome.Dictionary
$ xdg-app run --command=ls org.gnome.Dictionary ~/
<homedir listing...>

This can then again be overridden in a specific instance:

$ xdg-app run --nofilesystem=home --command=ls org.gnome.Dictionary ~/

There are quite a few options that control sandbox permissions. So, I’m going to list some useful examples of what can be done. (Note that all options have a negative version too, i.e. –unshare undoes –share.)

Grant access to some of your files:

  --filesystem=host    # All files
  --filesystem=home    # Your homedirectory
  --filesystem=home:ro # Your homedirectory, read-only
  --filesystem=/some/dir --filesystem=~/other/dir # paths
  --filesystem=xdg-download # The XDG Download directory
  --nofilesystem=...   # Undo some of the above

Allow the application to show windows using X11:

--socket=x11 --share=ipc

Note: –share=ipc means that the sandbox shares ipc namespace with the host. This is not necessarily required, but without it the X shared memory extension will not work, which is very bad for X performance.

Allow OpenGL rendering:


Allow the application to show windows using wayland:


Let the application play sounds using pulseaudio:


Let the application access the network:


Note: Giving network access also grants access to all host services listening on abstract unix sockets (due to how network namespaces work), and these have no permission checks. This unfortunately affects e.g. the X server and the session bus which listens to abstract sockets by default. A secure distribution should disable these and just use regular sockets.

Let the application talk to a named service on the session bus:


Let the application talk to a named service on the system bus:


Give the application unlimited access to all of dbus:

 --socket=system-bus --socket=session-bus

That was it for today. In the next part we’ll take a look at how to distribute your application.

Building an xdg-app – part 3

Welcome back to this multi-part tutorial in how to create xdg-app applications. In part 2 we built a an xdg-app for gnome-dictionary. However, if you look closely at the commands we used you will set not much what we did was specific to this application.

In fact, the only things related to gnome-dictionary are the:

  • application id
  • source url
  • binary name
  • necessary permissions

Why is this?

It turns out that most open source applications are built in very similar ways. One can even consider this an API for building modules. And if some module does not conform to this API, then it is easy to change the upstream to conform, or if upstream is not interested, apply a local patch.

The xdg-app-builder tool that ships with xdg-app is based on this idea. You describe your application, and the modules you want to build into it, and then xdg-app-builder takes care of calling the lower-level xdg-app build commands for you.

The equivalent of what we did in part 2 is this json:

  "app-id": "org.gnome.Dictionary",
  "runtime": "org.gnome.Platform",
  "runtime-version": "3.20",
  "sdk": "org.gnome.Sdk",
  "command": "gnome-dictionary",
  "finish-args": [ 
  "modules": [
      "name": "gnome-dictionary",
      "sources": [
          "type": "archive",
          "url": "",
          "sha256": "efb36377d46eff9291d3b8fec37baab2355f9dc8bc7edb791b6a625574716121"

If you put this in a file called org.gnome.Dictionary.json you can build and export the app using:

$ xdg-app-builder --repo=repo appdir3 org.gnome.Dictionary.json

And to test this you use:

$ xdg-app --user update org.gnome.Dictionary
$ xdg-app run org.gnome.Dictionary

So the above commands downloaded the files, initialized the build dir, built the modules, finished the app and exported it to the repo. Just like we did before.

However, even for this simple file it did a lot of other nice things too.

  • It verified the sha256 checksum of the downloaded tarball
  • It built all sources in a fixed location (in /run/build) to ensure more repeatable builds.
  • It ran the builds without access to any part of the host filesystem, other than the directory with the extracted sources. This means less chance of the build machine details affecting the build.
  • It automatically extracted all the debug information from the installed binaries into separate files, and these were commited to a separately installable runtime called org.gnome.Dictionary.Debug.
  • Translations were also extracted to separately installable runtimes called org.gnome.Dictionary.Locale.$lang
  • It cached each stage of the build, so that if you need to rebuild the app only the modules that have changed will be rebuilt.

Other than this xdg-app-builder has a lot of useful features. The obvious one is that you can build multiple modules into the application, and you can have multiple sources for each module. Sources can be of several types. Currently it supports: archive (.tar, .zip), git, bzr, patch files, and just running shell commands.

There is also a cleanup phase that happens after the build. This phase lets you remove things that was added during the build, that will not be needed during runtime. For instance, you can remove headers, development docs and similar things here. xdg-app-builder supports two properties for this. First a list of filename patterns, and secondly a list of commands to run during the cleanup phase.

"cleanup": [ "/include", "/bin/foo-*", "*.a" ]
"cleanup-commands": [ "sed s/foo/bar/ /bin/" ]

Additionally, the cleanup property can be set on a per-module basis, and will then only match filenames that were created by that particular module.

Another special feature is the rename-icon, rename-desktop-file and rename-appdata properties which lets you rename these kinds of files to match the application id. You have to do this because upstream files don’t use the application id in the name, which is not allowed by xdg-app during export.

The nightly build of the gnome applications all are built using xdg-app-builder, and you can get a lot of example json files there, for instance a complete version of gnome-dictionary built from git.  I also have a few more examples here.

For detailed documentations on all xdg-app-builder properties. See the man page for xdg-app builder.

That is it for today. Next time we will take a look at some details about the xdg-app sandbox.

Building an xdg-app – part 2

Welcome back to this multi-part tutorial in how to create xdg-app applications. In part 1 we installed everything we needed and manually created our first application. In this part we will build a more complex application, using the basic xdg-app tools.

I chose to build the gnome dictionary application, because its a small app with no dependencies. To build it we use the SDK (software development kit) that matches the runtime we used in the previous part. The SDK contains the development toolchain and the headers needed to build applications using the libraries in the runtime.

First we need to install the SDK. This is rather large, so it may take a while:

xdg-app --user install gnome org.gnome.Sdk 3.20

We also want the sources to the application we want to build:


Just like last time we start by creating the application directory where the application will be installed. However, this time we use the build-init command to create it:

xdg-app build-init appdir2 org.gnome.Dictionary org.gnome.Sdk org.gnome.Platform 3.20

This creates a directory called “appdir2” with a metadata file and the right directory structure. The only difference from last time is that the metadata file specifies a sdk as well as a runtime. A sdk is really just a runtime, but it is used during the build phase, rather than when the user runs the app.

Now that we have specified a sdk we can use the xdg-app build command. This is very similar to the run command, except it operates on an application build directory rather than an installed application, and it uses the sdk instead of the regular runtime. It also gives the sandbox access to all your files. For example, you can run:

$ xdg-app build appdir2 touch /app/some_file
$ xdg-app build appdir2 ls -l /app
total 0
-rw-r--r-- 1 alex wheel 0 Feb 19 16:03 some_file

This will have created a file “appdir2/files/some_file” in your tutorial directory.

Using this command you can build the application like you normally would, except in a sandbox. Since it is in a sandbox it will automatically use the compiler and other tools from the sdk. gnome-dictionary builds fine with a traditional configure; make; make install; incantation, so we only have to add a xdg-app prefix to these:

tar xvf gnome-dictionary-3.20.0.tar.xz
cd gnome-dictionary-3.20.0/
xdg-app build ../appdir2 ./configure --prefix=/app
xdg-app build ../appdir2 make
xdg-app build ../appdir2 make install
cd ..

We also need to give the app access to X11 and the network, and specify the command that is used to start the app. This is done with the build-finish operation:

xdg-app build-finish appdir2 --socket=x11 --share=network --command=gnome-dictionary

This adds some extra info to the metadata file, and creates the exports directory, which we’ll come back to later. You can install and try the app by running

xdg-app build-export repo appdir2
xdg-app --user install tutorial-repo org.gnome.Dictionary
xdg-app run org.gnome.Dictionary

You will see some warnings because we didn’t grant the app access to the dconf database, but other than that everything works.

On interesting new thing here is the exports mentioned above. If you look into the appdir2/export/ directory you will find this structure:

└── share
    ├── applications
    │   └── org.gnome.Dictionary.desktop
    └── dbus-1
        └── services
            └── org.gnome.Dictionary.service

And when the app is installed, these files will be exported into ~/.local/share/xdg-app/exports/. The xdg-app package then sets the XDG_DATA_DIRS environment variable to point to this directory, which means your desktop environment will look in it. This sounds a bit complicated, but what it means is that once the app is installed it will automatically appear among the normal applications in your desktop environment.

There is one limit on what gets exported though. All the filesnames (not directory names) must have the application id as a prefix. This works in the above setup because the desktop file is org.gnome.Dictionary.desktop, which is what we used for the id. This limitation guarantees that applications cannot cause conflicts, and that they can’t override any system installed applications.

We have now built a simple application with no dependencies. If there are any dependencies that are not in the runtime you need to build those too. This means more cycles of configure; make; make install; While this is not hard, it is a lot of manual repeated work. In the next part of this series we will see how this can be automated using the xdg-app-builder tool.