Choosing a security model


#1

Snaps are containerised to ensure predictable application behaviour and to provide greater security.

Containerisation is enforced at the system level, using Discretionary Access Controls (DAC), Mandatory Access Control (MAC) via AppArmor, Seccomp kernel system call filtering (which limits the system calls a process may use), and cgroups device access controls for hardware assignment.

When creating a snap, the extent of a snap’s containment is defined by the confinement keyword within its snapcraft.yaml:

confinement: devel

Confinement can be one of the following:

  • devmode: enables system access and logging only while creating a snap
  • strict: denies all system access other than through a snap’s interfaces
  • classic: permits full system-level access, analogous to a deb or rpm installation.

The vast majority of snaps should be able to attain strict confinement, but there are three specific requirements that can typically only be resolved with classic confinement:

  1. access to arbitrary filesystem paths outside of $HOME and /media
  2. run other programs that cannot be determined at build time
  3. perform privileged tasks not yet covered by interfaces (see below)

As a a result of these requirements, publishing a classic snap requires a review and approval process, alongside the manual addition of --classic to the snap command when the snap is installed.

:information_source: See Snap confinement for general details on confinement levels and the implications for the user.

From devel to strict

During the build and testing phase of snap development, it helps to have confinement set to devel, as shown in the example above. This is also the default when using the `snapcraft init’ command to initialise a new project directory.

To release a snap, its confinement needs to be either strict (in the majority of cases), or classic when a manual exception to its confinement needs to be made

To confine your application, return to your snapcraft.yaml file and change the confinement value from devmode to strict:

confinement: strict

You will also likely need to specify some interfaces. These are declarations that tell the system to give permission for a specific task, such as accessing a webcam or binding to a network port. You can find a list of interfaces and their intended purpose in the reference documentation.

The interfaces are specified as a list of “plugs” in your snapcraft.yaml file, alongside your command definition. For example, if your application needs access to the Internet and to the user’s home directory:

apps:
  offlineimap:
    command: bin/offlineimap
    plugs: [home, network]

If you have multiple command definitions, you will need to provide separate plugs definitions for each.

Now that your snapcraft.yaml is updated for confinement, rebuild your snap. This is a quick process when only the confinement method has changed.

Install and test your rebuilt snap. If your app continues to work as expected, you’re ready for publishing in the Snap Store.

See releasing your app for details on how to publish your snap.

Debugging

If your app has failed to start or behaves incorrectly, you may be missing some interfaces. Check journalctl -xe for a possible explanation, then refer to the interfaces in the reference documentation. Add any missing interfaces to your plugs definition, rebuild your snap, and test again.

If no explanation can be found, ask for assistance on the Snapcraft Forum. Be sure to include any relevant details, such as the contents of log files and any error messages printed on the terminal.


Releasing to the Snap Store
Creating your developer account
Proposed new documentation outline
Snap Documentation
Snapcraft build, debug and publishing docs roadmap (page breakdown)
#2

@jdstrand this is a doc topic you might have further input on


#3

Note that this path is not available in Debian-derived distros (/var/log/syslog), maybe using the journalctl command is more appropriate.


#4

Thanks @Lin-Buo-Ren, fixed.


#5

Maybe it’s best to also talk about snappy-debug.security scanlog instead of only journalctl -xe, since scanlog actually gives you hints about which interfaces or actions can fix security violations. scanlog is currently explained in the “Identifying missing interfaces” part of the “debugging building snaps” docs: https://docs.snapcraft.io/debugging-building-snaps/6274