9.3 KiB
Frameworks
Definition
Frameworks are a direct extension of the Ubuntu Core. As such Frameworks have the following attributes:
- Frameworks exist primarily to provide mediation of shared resources (eg, device files, sensors, cameras, etc)
- Frameworks provide a significant benefit for many users
- Frameworks are delivered via snaps
- Frameworks can be installed on the same system without conflicts
- Frameworks typically will use a toplevel namespace
- Framework
binariesmay be used without appending the package name and these binary names are governed by the framework onboarding process (below) - Frameworks run in a carefully crafted security profile
- Frameworks are tightly coupled with separately maintained security policies that extend the security policy available to apps consuming a framework
- Frameworks are developed and iterated by parties that have a contractual relationship with Canonical
- Frameworks in the official Ubuntu store are designed jointly with Canonical as part of the framework onboarding process
- Framework policies in the official Ubuntu store are controlled, designed, and developed by Canonical with the framework authors as part of that process
- Framework policy will automatically be installed when a framework is installed
- Unlike apps, frameworks have special permissions which allow them elevated access to the system. For the official Ubuntu store, a contract will include terms to ensure framework safety and maintenance
Importantly, frameworks are not generally:
- used as a replacement mechanism for debs/rpms
- used as a method to share code (ie, don't create a framework with libraries just for the sake of apps to be able to use them)
- used as a method to bypass app isolation
- able to be forked (a user may of course always sideload a modified framework)
Note: snappy frameworks are somewhat different from the Ubuntu for Phones
click frameworks and are more
flexible. Most importantly, click frameworks for Ubuntu for Phones map to a
particular release and are contracts between the platform (OS) and apps. Snappy
splits out the platform (OS) and the framework such that the contract is split
between the framework and the platform release (OS) (the release and
installed frameworks can be seen via snappy info). As such, apps will
specify the release they target (implementation covered elsewhere) and any
frameworks they require.
Store process
Initially, frameworks and framework policy will be shipped in the same snap which will ensure that framework policy is always in sync with the framework for which it applies. To support this:
- Frameworks must always specify framework policy, otherwise the store will reject it
- Framework snaps will always trigger a manual review to ensure the framework policy has not changed. Alternatively, the first upload could require manual review, but subsequent uploads could be automatically approved if the security policy does not change
- For frameworks shipped in the official Ubuntu store, framework authors will enter a contract to provide any needed security updates and not be malicious
For the official Ubuntu Store, we may eventually allow separate ownership of frameworks from framework policies.
Usage
framework yaml
For frameworks, meta/package.yaml should contain something like:
name: foo
version: 1.1.234
type: framework
services:
- name: bar
description: "desc for bar service"
start: bin/bar
binaries:
- name: bin/baz
description: "desc for baz binary"
Required fields for framework snaps:
type: framework- defines the type of snap this is
Frameworks will typically need specialized security policy. See security.md
for details.
In addition to the above yaml fields, the security policy used by apps is
shipped in the meta/framework-policy directory according to the following
hierarchy:
meta/framework-policy/apparmor/policygroups/group1group2
templates/template1template2
Because frameworks must be coinstallable, all shipped policy files will be
prepended with the framework name followed by an underscore. Apps must
reference the policy using the full name. For example, if the foo framework
ships meta/framework-policy/apparmor/policygroups/bar-client, then apps must
reference this as foo_bar-client.
While the above provides a lot of flexibility, it is important to remember a
framework snap need only provide what apps will use. For example, if the foo
framework is designed to have clients connect to the bar service over DBus,
then the framework snap might provide
meta/framework-policy/apparmor/policygroups/foo_bar-client and nothing else.
The contents of files in the apparmor directory use apparmor syntax as
described in apparmor.d(5). When specifying DBus rules, set the peer label to
refer to the AppArmor label (APP_ID) of the service to be accessed. Also, to
ensure frameworks are coinstallable, the service should be implemented so its
DBus path uses the format /pkgname/service.
For example, using the above example where the foo framework ships a bar
DBus system service, a bin/exe utility, some data files and also a runtime
state file, then meta/framework-policy/apparmor/policygroups/bar-client
might contain something like:
/apps/foo/*/bin/exe ixr,
/apps/foo/*/data/** r,
/var/lib/apps/foo/*/run/state r,
dbus (receive, send)
bus=system
peer=(label=foo_bar_*),
App yaml
For apps wanting to use a particular framework, meta/package.yaml simply
references the security policy provided by the framework. Eg, if a service in
the norf app wants to access the bar service provided by the foo
framework in the above framework yaml example, it might use:
name: norf
version: 2.3
frameworks:
- foo
services:
- name: qux
description: "desc for qux service"
start: bin/qux
caps:
- networking
- foo_bar-client
See security.md for more information on specifying caps and a
security-template as provided by the framework snap.
User experience
The command line experience is:
$ snappy search foo
Name Version Description
foo 1.1.234 The foo framework
$ snappy install foo
Installing foo
Starting download of foo
4.03 MB / 4.03 MB [==============================] 100.00 % 124.66 KB/s
Done
Name Date Version Summary
foo 2015-03-16 1.1.234 The foo framework
$ snappy list
Name Date Version Summary
ubuntu-core 2015-03-16 333 ubuntu-core description
foo 2015-03-16 1.1.234 The foo framework
hello-world 2015-02-23 1.0.5
$ snappy list --updates
Name Date Version
ubuntu-core 2015-03-16 333 ubuntu-core description
foo* 2015-03-16 1.1.234 The foo framework
hello-world 2015-02-23 1.0.5
$ sudo snappy update
Installing foo (1.1.235)
4.03 MB / 4.03 MB [==============================] 100.00 % 124.66 KB/s
Done
Name Date Version Summary
foo 2015-03-17 1.1.235 The foo framework
$ snappy list --updates
Name Date Version
ubuntu-core 2015-03-16 333 ubuntu-core description
foo 2015-03-17 1.1.235 The foo framework
hello-world 2015-02-23 1.0.5
$ snappy remove foo
Removing foo
$ snappy info
release: ubuntu-core/devel-proposed
architecture: amd64
frameworks: foo
apps: hello-world
A convenience afforded to frameworks is that commands don't require that the
package name be appended. Eg, using the above package.yaml, either of these
may be used:
$ baz --version
1.1.235
Open questions
The following are considerations that may affect the above for when we build on this work:
-
define how to specify restricted security policy (perhaps simply refine what we do on Touch with meta information contained in the policy)
-
define how to allow certain apps to use restricted policy without manual review (perhaps have the framework define which apps are allowed to use the restricted policy. How? in the yaml? in the meta information in the policy? Something in the
meta/framework-policydirectory?) -
should we adjust
hw-assign/create svc-assignto support special framework services that perhaps don't provide sufficient app isolation, are privileged in some manner, etc? Eg, consider a DBus service that allows you to configure network interfaces. Framework provides thebar-srvservice and appbaz-appdeclares it wants to use that service viacaps. In the normal case, declaring incapswould be enough, butbar-srvis special in some way that we don't want the app to have access automatically. In this case we might use:`snappy svc-assign baz-app bar-srv` -
if we implement this, how should we declare
bar-srvaccess tobar-srvis restricted in this manner? -
should we allow users the ability to to use the
binarieswith the appended package name? Eg: $ baz.foo --version 1.1.235 -
...