It is no secret that we’ve been interested in sandboxed applications for a while. It is evident here, here, here or here, to name just a few.
What may not be widely known yet is that we have been working on putting together a working implementation of these ideas. Alexander Larsson has made steady progress, and we’re now almost at the point where it is useful for other people to start playing with it.
If you want to go straight to the playing part, you can head to this wiki page, which has all the links and explanations you need.
Some rights reserved by whiteoakart
Why sandboxed apps ?
There are several reasons:
- We want to make it possible for 3rd parties to create and distribute applications that work on multiple distributions.
- We want to run the applications with as little access as possible to the host (for example user files or network access), so that users can try applications without necessarily having to trust them fully.
- We want to make it much easier to write applications – jhbuild has its uses, but it is an endless source of frustration and a very high hurdle for new contributors.
Traditionally, the only answer available to people who need to distribute an executable that works across several Linux distributions is to statically link all but the lowest-level dependencies.
That is not only wasteful in terms of bandwidth for downloading, but also at runtime, when every application loads its own copy of those dependencies, instead of sharing them.
And the real problem comes when one of those dependencies needs to be updated, e.g. because of a security issue (some people still remember the infamous zlib double-free incident). Dealing with this in a fairly efficient way is a strong point of the Linux packaging model, as its proponents are quick to point out.
So, are sandboxed apps any better ? By themselves, they aren’t.
Runtimes and bundles
We suggest to introduce the concept of a runtime to help with this. A runtime provides a well-defined environment that an app can run in – one way to think of it is as a /usr filesystem with fixed contents.
Typical examples would be “GNOME 3.14” or “KDE 5.6”.
It is important to note: you can have multiple runtimes installed on the system, and even multiple versions of the same runtime. Things that are not included in the runtime will still have to be bundled with the application – but the problem becomes much more manageable.
What about the applications themselves ? In the filesystem, an app bundle is simply a directory which contains a metadata file that describes the application, what runtime it needs, and various other things. The actual contents of the app bundle are in a subdirectory. The last component of an app bundle is another subdirectory, containing the various files that are needed by the host system and the session to present the app to the user: desktop files, icons, etc.
The only way to run such a bundled application is through a helper, which sets up the sandbox. It uses kernel namespaces and bind mounts to isolate the application from the host system and its filesystem. The app bundle contents get mounted under /self, and the runtime gets mounted under /usr.
But what about the developer experience ? The runtime idea has a counterpart that helps with this, the developer runtime, or sdk. It is basically, the runtime with the ‘devel’ parts added, including tools like a compiler and a debugger. And similar to the ‘xdg-app run’ command that sets up a sandbox to run an application in, there is an ‘xdg-app build’ command that sets up a ‘developer sandbox’ with the sdk.
Is this progress ?
One question I expect is: What about freedom ? This sounds just like corporate walled gardens and app stores. I think this is a fair question – we are trying to replicate some of the strong points of the app store model. The existing examples of this model have a strong flavor of control, and focus entirely on consumption as opposed to creation.
But I think we can actually turn this into a freedom-enhancing change, if we pay attention while building it.
One vision I have is that we could have a “Modify this application” context menu item in gnome-shell which downloads the sources of the app bundle, sets up the right sdk, opens the sources in your favourite IDE, where you can make your modifications, build it, test it and create a new bundle that you can share with your friends.
In particular the last part (wrapping your modifications in an easy-to-share form) is really not easy in the traditional distribution world, where everything has to be a package that comes from your distributor.
This might be a great fit for gnome-builder, which will hopefully gain support for building bundled applications. Coincidentally, the gnome-builder project is just entering the last week of its fundraising campaign – if you haven’t donated yet, you have 7 days left to do so.
Some notable facts about the implementation that Alex’ has been working on:
- Both runtimes and app bundles can be installed per-user and system-wide, and they can coexist perfectly fine with traditional applications. There’s no need for everybody to adopt this model at once, we can transition gradually to it.
- We use OSTree to distribute both runtimes and applications as well as updates. OSTree is a good fit for this, because its use of content-based addressing and hardlinks transparently makes runtimes and bundles share disk space, and at the same time it doesn’t impose strong requirements on the host system. But OSTree does not have to be the only distribution mechanism – the definition of the filesystem layout for applications and the sandboxing setup is has no dependencies on it.
- The build tooling supports using rpmbuild and rpms to build runtimes and application. With this, what we do becomes very similar to the rpm-ostree project: They use rpms to populate OS images on the server side, we use rpms to put together runtimes and applications. In both cases, the results get distributed to end users via OSTree.
- We have a repository with a few example applications and a yocto-based runtime for GNOME 3.15.
Whats next ?
There are lots of smaller (and some bigger things left to do).
Currently, we are working on making gnome-software show and handle these application bundles in addition to traditional packaged applications.
Our short-term goal is to provide an initial test version of a ‘reference runtime’ for the GNOME 3.16 release.
If you want to learn more, you can study the SandboxedApps wiki page that I’ve already mentioned, or you can come to DevConf.cz, where Alex will be presenting his work.
13 thoughts on “Sandboxed applications for GNOME”
Great idea, have you thought of using Docker for this? For example the base layer(or image) is your `runtime`. And all other images append to it will be the user app. Since each layer has its own SHA1, you can make a forest of different layers that can be shared form all user applications, but use smaller HDD footprint.
Having the same technology for servers and desktop will bring so much value for Linux.
Sounds to me like the Pöttering idea with btrfs subvolumes and also runtimes as dependencies for app images.
I think this can be wonderfully combined with this approach.
Though the toughest Problem would be duplicated libraries that need to be shipped with certain applications. Or different library versions used as runtime dependency by different apps causing more disk space usage then traditional package-management driven solutions.
I know btrfs deduplication could be helpful here but still there will be an overhead.
I wonder if that can be ever reduced
This is awesome! This could make linux more unified and allow for more apps included in the repos/software center!
What I do however wonder is how the permission model is designed, if an application wants to use the GPS does the user decide (iOS like) or does the application state it during installation (android like)?
Did you examine Nix? It solves that problem at package manager level (and expands it into a Linux Distribution – NixOS) http://nixos.org/nix/about.html
While Fedora is a first-class citizen, I sometimes come across software that has Ubuntu packages and source packages. No RPMs. So if more people adopt this (and it doesn’t fail like similar initiatives in the past), it would be GREAT. Less work for developers to support multiple distros and less work for the distro packagers. I imagine they would essentially be doing QA at that point and maybe some security auditing before a package went into the repo.
A few thoughts:
It would be nice if the runtime requirement could be specified as e.g. KDE/5.6+ (meaning later). I think both GNOME and KDE are backwards compatible. This would allow saving bandwith/disk space/memory, and enable features of newer runtime versions for the application bundle. It might be useful to allow installing/using an older runtime version, in case there are regression/imcompatibilities.
I think runtime version in this case should be specified as KF5/5.6+ or GNOME3/3.18+ or something similar.
Regarding runtime installation: For a private computer, e.g. used by a family, system wide installation (secured by e.g. policykit) is the most useful case. For enterprise usage, especially when using VDI, it might be useful to allow or disallow user installations (depending on user, repository, …), and also give administrators a possibility to query runtimes used/installed user wide.
I see no pictures when visiting this site via HTTPS:
I don’t know what to do about that, sorry.
Use portocol-relative URLs.
Sounds interesting, but I think what the app developer really wants is one stable API to build against for any distro/de and not having to choose to code against gnome3.14, gnome3.16 or kde5.4, but rather against linux64-1.0. linux64-1.0 would be a shared library (or multiple ones) and a header implementing the api, there could be implementations against gnome 3.14, gnome-git-current, xaw-1.0. Any de/distro then could ship one or more chosen implementations and any app would only have to link against one api: bingo, full flexibility on the distro side, naximum coverage for the app developer. The api would define stuff gui elements, database manipulation, and various file formats and stuff. Now, the only minor problem is to get all distros, toolkit and de people to agree on the actual api, I guess…
I am long-time Linux desktop app developer that has worked on projects primarily delivered through package management systems. So, I understand the motivation and like what you are trying to do. My latest project is Shotcut, which is primarily delivered and run as a non-statically-linked, no-install app bundle. If I adopt this asap, I have a strong feeling that very few users will be able to actually use it for a while because it will require such a new, specific distro. Meanwhile, what I provide now already runs on many distros. Talk to people who already deliver app bundles. I was inspired by some Humble Indie Bundle games.
The biggest problems I have faced in this area are:
1.) A way to test for missing, non-bundled libs (I really like runtimes part of the proposal.)
2.) A reliable way to run a relative executable from .desktop. My current hack works on many file managers but not all.
3.) Support for a relative path to the app icon in .desktop. Currently, I just use a generic category icon.
Wow, look how simple that is compared to the proposal! As the app developer, I do not care about the sandbox, but as long as it is not too draconian and largely provided by some new OS version to benefit the user, that is fine. I am not opposed to do something special at build-time to be compatible with the sandbox as long as its not too burdensome.
Making improvements to app delivery does not need to depend on sandboxing because app bundles are already possible – just in a less-than-ideal fashion. I am inclined to reject any new APIs and reluctant to use a filesystem bundler. Like some OS X .app bundles and Windows program folders, my bundle has some handy command line utilities one can access without first having to mount a file system.
Is there any cooperation, contact or conversation about this with other desktops (KDE, Unity, etc.)? Will applications built to work with this sandboxing work correctly on other DEs, and applications from other DEs still work correctly in GNOME?
something to be worried about
Comments are closed.