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 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:
- access to arbitrary filesystem paths outside of
- run other programs that cannot be determined at build time
- 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.
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
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.
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.