This document extends the Apertis Applications concept design to cover metadata about application bundles (app-bundles).

Terminology and concepts

See the Apertis glossary for background information on terminology. Apertis-specific jargon terms used in this document are hyperlinked to that glossary.

Use cases

These use-cases are not exhaustive: we anticipate that other uses will be found for per-application-bundle metadata. At the time of writing, this document concentrates on use-cases associated with assigning priorities to requests from an app-bundle to a platform service.

Audio management priorities

Assume that the Apertis audio management component (which is outside the scope of this document) assigns priorities to audio streams based on OEM-specific rules, potentially including user configuration.

Suppose the author of an app-bundle has a legitimate reason to have their audio streams played with an elevated priority, for example because their app-bundle receives voice calls which should take precedence over music playback.

Also suppose a different, malicious app-bundle author wishes to interrupt the driver’s phone call to play an advertisement or other distracting sound as an audio stream.

The Apertis system must be able to distinguish between the two app-bundles, so that requests for an elevated priority from the first app-bundle can be obeyed, while requests for an elevated priority from the second app-bundle are rejected.

We assume that the app-bundles have been checked by an app-store curator before publication, and that the first app-bundle declares a special permission in its app manifest, resulting in the app framework allowing it to flag its audio stream in ways that will result in it being treated as important, and hence superseding less important audio. Conversely, if the second app-bundle had declared that permission, we assume that the app-store curator would have recognised this as inappropriate and reject its publication.

Notification and dialog priorities

Assume that the Apertis compositor (which is outside the scope of this document) assigns priorities to notifications based on OEM-specific rules, potentially including user configuration. Depending on the OEM’s chosen UX design, app-modal and system-modal dialogs might be treated as visually similar to notifications; if they are, the compositor author might also wish to assign priorities from the same ranges to dialogs.

Similar to the Audio management priorities use case, app-bundles that have a legitimate reason for their notifications or dialogs to be high-priority must be able to achieve this, but malicious app-bundles whose authors aim to misuse this facility must not be able to achieve an elevated priority.

App-bundle labelling

A UX designer might wish to arrange for all user interface elements associated with a particular app-bundle (including notifications, windows, its representation in lists of installed app-bundles, and so on) to be marked with an unambiguous indication of the app-bundle that created them, such as its name and icon.

In particular, the Compositor Security concept design (which is work in progress at the time of writing) calls for windows and notifications to be visually associated with the app-bundle that created them, so that malicious app-bundle authors cannot make the user believe that information presented by the malicious app-bundle came from a different app-bundle (output integrity), and also cannot convince the user to enter input into the malicious app-bundle that they had only intended to go to a different app-bundle (a trusted input path, providing input confidentiality for the non-malicious app-bundle).

Note this mechanism will not be effective unless either the app-store curator avoids accepting app-bundles with the same or confusingly similar names or icons, or the UX designer disambiguates app-bundles using something that is guaranteed to be unique, such as the app-bundle ID (which is not necessarily a desirable or user-friendly UX). This applies wherever app-bundles are listed, such as the app store’s on-device user interface, the app-store’s website, or a list of installed app-bundles in the device’s equivalent of Android’s Settings → Apps view.

Requirements

App-bundle metadata

An Apertis platform library to read app bundle metadata must be made available to platform components, featuring at least these API calls:

  • given a bundle ID, return an object representing the metadata
  • list all installed bundles (either built-in or store) with their IDs and metadata
  • emit a signal whenever the list of installed bundles changes, for example because a store app bundle was installed, removed, upgraded or rolled back (simple change-notification)

Labelling requirements

Each app-bundle must contain a human-readable name in international English. It must also be possible for an app-bundle to contain translated versions of this name for other languages and locales, with the international English version used in locales where a translation is not provided.

Each app-bundle must be able to contain the name of the authoring company or individual.

Each app-bundle must contain a version number. To let the application manager make appropriate decisions, all application bundles must a format for their version strings that can be compared in a standard way. How an application developer chooses to set the version numbers is ultimately their decision, but Apertis must be able to determine whether one version number is higher than another.

Collabora recommends requiring version numbers to be dotted-decimal (one or more decimal integers separated by single dots), with “major.minor.micro” (for example 3.2.4) recommended but not strictly required.

There will be a “store version” appended to the version string after a dash, similar to the versioning scheme used by dpkg; for example, in the version string 3.2.4-1, the 1 is the store version. The store version allows the store to push an update even if the application version hasn’t changed, and it will be the lowest significant figure. For example, version 2.2.0-1 is newer than version 2.1.99-4. The store version will re-start at 1 any time the application version is increased, and will be incremented if a new intermediate release is required.

Secure identification

Apertis platform services that receive requests from an unknown process must be able to identify which app-bundle the process belongs to. To support this, the request must take place via a channel that guarantees integrity for that process’s identification: it must not be possible for a malicious process to impersonate a process originating from a different app-bundle.

Audio stream and notification requirements

The information required by the audio manager must be represented as one or more metadata key-value pairs that can be read from the app bundle metadata.

The information required by the notification implementation must be represented as one or more metadata key-value pairs that can be read from the app bundle metadata.

We anticipate that audio management and notifications will not always assign the same priority to each app-bundle, therefore it must be possible for the metadata keys used by audio management and those used by notifications to be distinct.

App-store curator oversight

It must be straightforward for an app-store curator to inspect the metadata that is present in an app-bundle, for example so that they can refuse to publish app-bundles that ask for audio or notification priorities that they have no legitimate reason to use, or for which the name, icon or other information used for App-bundle labelling is misleading.

Store app-bundle confidentiality

Ordinary unprivileged programs in store app-bundles must not be able to use these API calls to enumerate other installed store app-bundles. For example, if those API calls are implemented in terms of a D-Bus service, it must reject method calls from store app-bundles, or if those API calls are implemented in terms of reading the filesystem directly, store app-bundles' AppArmor profiles must not allow reading the necessary paths.

Non-requirement: it is acceptable for ordinary unprivileged programs to be able to enumerate installed built-in app-bundles. Built-in app-bundles are part of the platform, so there is no expectation of confidentiality for them.

Extension points

We anticipate that vendors will wish to introduce non-standardized metadata, either as a prototype for future standardization or to support vendor-specific additional requirements. It must be possible to include new metadata fields in an app-bundle, without coordination with a central authority. For example, this could be achieved by namespacing new metadata fields using a DNS name (as is done in D-Bus), namespacing them with a URI (as is done in XML), or using the X-Vendor-NewMetadataField convention (as is done in email headers, HTTP headers and freedesktop.org .desktop files).

Future directions

Platform API requirements

The application bundle metadata should include a minimum system version (API version) required to run the application, for example to prevent the installation of an application that requires at least Apertis 16.12 in an Apertis 16.09 environment. A specific versioning model for the Apertis API has not yet been defined.

Declarative permissions

The application bundle metadata should include simple, declarative permissions which can be used to generate an AppArmor profile in an automated way. The Permissions concept design tracks this work.

Declaring system extensions

The Applications concept design calls for app-bundle metadata to describe the types of system extension (themes, addons, plugins, etc.) provided by an app-bundle. There is currently no detailed specification for this.

AppStream upstream XML already supports declaring that a component (app-bundle) is an addon to another component (via the addon type) or to the system as a whole (via the <provides> element). There is no specific metadata to describe themes; discussion has been started in AppStream issue 67.

Declaring where applications store non-essential files

The Applications concept design suggests that application bundle metadata might declare where applications store non-essential files, so that the system can delete those files when disk space runs out.

The Applications concept design suggests that for applications not originally designed for Apertis, which might write to locations like ~/.someapp, application bundle metadata might declare where the platform must create symbolic links to cause those applications to read and write more appropriate locations on Apertis, for example ~/.someapp → /var/Applications/com.example.SomeApp/users/${UID}/data.

Declaring an EULA

App-bundle metadata should include a way to specify an EULA which the user must agree with before the application bundle will be installed. See AppStream issue 50 for work on this topic in the AppStream specification.

Other files in the license directory of the bundle but not mentioned in this way will still be copied the device, and the HMI components must provide some way to view that information later.

Placeholder icons

Since the installation process is not instant, a placeholder icon should be provided and specified in the version of the application bundle metadata that is downloaded from the application store. This icon will be copied into the store directory by the application store during publication. It will be displayed by the application manager instead of the application until the installation is completed. The application launcher will also be able to display a progress indicator or – if multiple applications are being installed – a position in the install queue.

Platform component metadata

Although it is not a requirement at this stage, we anticipate that it might be useful in the future to be able to associate similar metadata with platform components, such as the Newport download manager.

Other systems

This section contains a very brief overview of the analogous functionality in other open-source platforms.

freedesktop.org AppStream

Several open-source desktop platforms such as GNOME and KDE, and Linux distributions such as Ubuntu and Fedora, have adopted AppStream as a shared format for software component metadata, complementing the use of .desktop files for entry points.

The AppStream specification refers to components, which are a generalization of the same concept as Apertis app-bundles, and can include software from various sources, including traditional distribution packages and bundling technologies such as Flatpak.

Flatpak

The Flatpak framework provides user-installable applications analogous to Apertis app-bundles. It uses AppStream for app-bundle metadata, together with .desktop files for entry points.

Snappy

Ubuntu Snappy packages (snaps) are also analogous to Apertis app-bundles. Their metadata consists of a Snappy-specific YAML file describing the snap, again together with .desktop files describing entry points.

Android

Android apps are its equivalent of Apertis app-bundles. Each app has a single App manifest file, which is an XML file with Android-specific contents, and describes both the app itself, and any activities that it provides (activities are analogous to Apertis entry points).

Design recommendations

The Apertis Application Bundle Specification describes the metadata fields that can appear in an application bundle and are expected to remain supported long-term. This document provides rationale for those fields, suggested future directions, and details of functionality that is not necessarily long-term stable.

App-bundle metadata design

We anticipate that other designs involving app-bundles will frequently require other metadata beyond the use-cases currently present in this document, for example categories. As such, we recommend introducing a general metadata file into built-in and store app-bundles.

This metadata file could have any syntax and format that is readily parsed. To minimize duplicate effort, we recommend using AppStream XML, a format designed to be shared between desktop environments such as GNOME and KDE, and between Linux distributions such as Ubuntu and Fedora.

Each built-in app bundle should install an AppStream upstream XML metadata file. If the built-in app bundle has entry points, then its metadata file must be made available as /usr/share/metainfo/${bundle_id}.appdata.xml (where ${bundle_id} represents its bundle ID), and its <id> must be <id type="desktop">${entry_point_id}.desktop</id> where ${entry_point_id} represents its primary entry point (typically the same as the bundle ID). /usr/share/metainfo/${bundle_id}.appdata.xml will typically be a symbolic link to /usr/Applications/${bundle_id}/share/metainfo/${bundle_id}.appdata.xml.

If the built-in app bundle has no entry points (for example a theme), then its metadata file must be available as /usr/share/metainfo/${bundle_id}.metainfo.xml (where ${bundle_id} represents its bundle ID), and its <id> must be the same as its bundle ID. Again, this would typically be a symbolic link to a corresponding path in /usr/Applications/${bundle_id}.

Each store app bundle should install an AppStream upstream XML metadata file into /Applications/${bundle_id}/share/metainfo/${bundle_id}.appdata.xml or /Applications/${bundle_id}/share/metainfo/${bundle_id}.metainfo.xml (depending on whether it has entry points), with contents corresponding to those specified for built-in app bundles. For Store app-bundle confidentiality, a store app-bundle’s AppArmor profile must not allow it to read the contents of a different store app-bundle, and in particular its AppStream metadata.

AppStream upstream XML is normally also searched for in the deprecated path /usr/share/appdata, but for simplicity, we do not require the share/appdata/ directory to be processed for application bundles. Since existing application bundles do not contain it, this does not create a compatibility problem.

For App-store curator oversight, if the implementation reads other sources of metadata from a store app-bundle (for example the .desktop entry points provided by the app-bundle), then the implementation must document those sources. The app-store curator must inspect all of those sources. This requirement does not apply to built-in app-bundles, which are assumed to have been checked thoroughly by the platform vendor at the time the built-in app-bundle was integrated into the platform image.

The Apertis platform must provide cache files whose timestamps change whenever there is a change to the set of store or built-in app bundles, or to those bundles' contents. These cache files should be monitored by the libcanterbury-platform library, using the standard inotify mechanism. Any cache files that contain store app-bundles must not be readable by a store app-bundle, to preserve Store app-bundle confidentiality.

The other APIs that are required are straightforward to implement in the libcanterbury-platform library by reading from the cache files. Because this is done in a library (as opposed to a D-Bus service), the implementation of these APIs will run with the privileges of the process that is requesting the information: in particular, if an unprivileged process attempts to read the cache files, this will be prevented by its AppArmor profile, regardless of whether it is using libcanterbury-platform or reading the files directly.

We recommend that store app-bundles and built-in app-bundles appear in separate cache files, for several reasons:

  • In the current design for Apertis operating system upgrades, the metadata files for built-in app-bundles and platform components in /usr/Applications/*/share/* and /usr/share/* are only updated during an operating system upgrade, by either dpkg or by unpacking a new OS filesystem hierarchy that will be activated after the next reboot. In the dpkg case, it is sufficient to have a dpkg trigger monitoring these directories, and update the built-in app-bundle cache when they have changed, leaving the store app-bundle cache unchanged. Similarly, in the whole-OS upgrade case, the built-in app-bundle cache can be provided in the new OS filesystem or rebuilt during startup, again leaving the store app-bundle cache unchanged.

  • Conversely, the metadata files for store app-bundles are updated by the Ribchester subvolume manager when it installs a new store app-bundle, which can occur at any time. When it does this, it is sufficient to update the store app-bundle cache, leaving the built-in app-bundle cache unchanged.

  • If Apertis moves to a more static model for deployment of the platform (for example using disk images or OSTree to deploy pre-built filesystem hierarchies), the built-in app-bundle cache would be entirely static and could be included in the pre-built filesystem hierarchy.

  • Using separate caches makes it straightforward to ensure that if a store app-bundle with the same name as a built-in app-bundle is somehow installed, the built-in app-bundle takes precedence.

Any metadata keys and values that have not been standardized by the AppStream project (for example audio roles that might be used to determine a bundle’s audio priority) must be represented using Extension points within the AppStream metadata. The formal AppStream specification does not provide an extension point, but the reference implementation and appstream-glib both provide support for a <custom> element with <value> children. We recommend using that element for extension points. See the Apertis Application Bundle Specification for details.

When a store or built-in app-bundle is added, removed or changed, the Apertis platform must update the corresponding cache file.

Future directions

AppStream XML is equally applicable to platform components, which can install metadata in /usr/share/metainfo in the same way as built-in app-bundles.

Because built-in app-bundles and platform components have the same update schedule and are managed by the same vendor (they are both part of the platform), we anticipate that platform components should use the same cache file as built-in app-bundles.

Secure identification design

Consumers of requests from app-bundles, such as the audio manager or the notifications implementation, must receive the bundle ID alongside the request using a trusted mechanism. If the request is received via D-Bus, the bundle ID must be retrieved by using the GetConnectionCredentials method call to receive the AppArmor context, then parsing the context to get the bundle ID and whether it is a store or built-in app-bundle. If the request takes the form of a direct AF_UNIX socket connection, the bundle ID must be retrieved by reading the SO_PEERCRED socket option, then parsed in the same way. Consumers of app-bundle priorities should do this by using the CbyProcessInfo objects provided by libcanterbury.

Because the Apertis Security concept design does not place a security boundary between different processes originating from the same app-bundle, all identification of app-bundles should be carried out using their bundle IDs. In particular, consumers of requests from app-bundles should only use the requester’s AppArmor label to derive its bundle ID and whether it is a store or built-in app-bundle, and must not use the complete AppArmor label, the complete path of the executable or the name of the corresponding entry point in access-control decisions.

Labelling design

AppStream upstream XML already contains standardized metadata fields for a name, author name etc.

The name (and several other metadata fields) can be translated via the xml:lang attribute. For example, GNOME Videos (Totem) has many language-specific names, starting with:

  <name>Videos</name>
  <name xml:lang="af">Video's</name>
  <name xml:lang="ar">فيديو</name>
  <name xml:lang="as">ভিডিঅ'সমূহ</name>
  <name xml:lang="be">Відэа</name>

AppStream upstream XML does not include an icon, although the derived AppStream collection XML format published by redistributors does. We recommend that the app-bundle should contain a PNG icon whose name matches its bundle ID, installed to its share/ directory as part of the hicolor fallback theme.

The reserved icon theme name hicolor is used as the fallback whenever a specific theme does not have the required icon, as specified in the freedesktop.org Icon Theme specification. The name hicolor was chosen for historical reasons.

For example, com.example.ShoppingList would include /Applications/com.example.ShoppingList/share/icons/hicolor/64x64/apps/com.example.ShoppingList.png. If the app-store uses AppStream collection XML, then the process used to build AppStream collection XML from individual applications' AppStream upstream XML files should assume this icon name and include it in the collection XML.

Open question: We should require a specific size for the icon, to avoid blurry or blocky app icons caused by resizing. GNOME Software uses 64×64 as its baseline requirement, but recommends larger icons, for example 256×256. iOS uses 1024×1024 for the App Store and ranges from 60×60 to 180x180 for on-device icons. [Android][Android icons sizes] uses 512×512 for the Google Play Store and ranges from 36×36 to 96×96 for on-device icons. What are our preferred sizes?

Future directions

Platform components that are not part of an app-bundle do not have bundle IDs. We anticipate that Platform component metadata might be identified by a separate identifier in the same reversed-DNS namespace, and that the consumer of requests might derive the platform component identifier by looking for components that declare metadata fields matching the requester’s AppArmor label (part of the AppArmor context).

Summary

  • app-bundle metadata is read from the cache that summarizes built-in and store app-bundles. The libcanterbury-platform library provides the required APIs; in particular, change notification can be done using inotify.
  • Secure identification is provided by [parsing the requesting process’s AppArmor context][Secure identification design].
  • The Audio stream and notification requirements are addressed by providing their desired metadata in the app-bundle metadata, in the form of arbitrary key/value pairs.
  • App-store curator oversight is facilitated by documenting all of the sources within a store app-bundle from which the implementation gathers metadata to populate its cache.
  • Store app-bundle confidentiality is provided by storing the cache file describing installed store app-bundles in a location where store app-bundles cannot read it, and by avoiding the need to introduce a D-Bus service from which they could obtain the same information.
  • The appstream-glib library supports Extension points in AppStream XML.