Model assertion

Model assertion

The model assertion is a text-based document that contains the fundamental definition of a snap-based device. It describes what the system image includes and is signed by the brand account owning the device definition.

The model assertion contains:

  • Identification information, such as brand account id and model name.
  • Which essential snaps make up the device system, including the gadget snap, kernel snap and the boot base snap with the root filesystem.
  • Other required or optional snaps that implement the device functionality.
  • Additional options for the defined device, such as grade for a UC 20 device.

The model assertion is central to both the creation of the device image and the deployed device’s lifecycle, in particular it:

  • drives image creation via ubuntu-image. The resultant system seed includes the set of snaps and assertions specified in the model assertion.
  • allows first boot verification of the system seed before its snaps are turned into an installed system.
  • conveys model information, through registration from either the factory or in the field, which is used for cross-checking and registration affecting options, such as which account can issue a serial assertion for the device.

For more details on using a model assertion to create an image, see Custom images.

Model assertion fields

The following fields can be used in a model assertion:

type:              model
architecture       <debian architecture name>
authority-id:      <authority account id>
base:              <string>
brand-id           <account id>
classic            <true|false>   # optional
display-name       <descriptive string>
grade:             <string>
model              <model id>
required-snaps     <string>
revision:          <int>
serial-authority   <list<string>> # optional
series             <string>
sign-key-sha3-384: <key id>       # Encoded key id of signing key
snaps:             <list[dict]>   # See below for details
store              <string>       # optional
storage-safety     <string>       # optional
timestamp          <UTC datetime>

The index for this assertion is the tuple <series, brand-id, model> and the fields are typically used in the following order:

  • series allows the brand to define which release of the platform the device uses. “rolling” is the name of the development series that bridges stable series, which have names like “16” or “18”.

  • authority-id and brand-id fields define the authority signing the assertion. Reference assertions are signed by Canonical and non-reference assertions are signed by their brand store. For a custom model assertion, this needs to be the developer ID.

  • model is a string that identifies a set of devices as desired by the brand.

  • architecture is the Debian architecture name, such as amd64.

  • storage-safety is used to request that Ubuntu Core 20 installs with or without full disk encryption. It can be omitted or one of either:

    • prefer-unencrypted: do not encrypt by default, even if the device supports encryption.
    • prefer-encrypted: do encrypt if the hardware supports it.
    • encrypted: ensure encryption is used and fail if the device does not support it.
  • timestamp can be generated with the date -Iseconds --utc command.

  • base provides the run-time environment. core20 is the newest base, built from Ubuntu 20.04 LTS. core18 is the current standard base and is built from Ubuntu 18.04 LTS. See Base snaps for more details.

  • grade sets the constraints for the device. It can be one of the following:

    • dangerous: relax some of the constraints here (mandatory snap id for example), and should allow for the use of unasserted snaps, devmode snaps, or the presence of extra snaps in the recovery system.
      Using dangerous does weaken security, and as a result, this grade is meant only for development purposes. For example, you could define a my-device-devel or my-device-dangerous model for development images in parallel to a my-device model for production.
    • signed (default): no unasserted (unsigned) snaps or snaps not mentioned in the model can appear or be used in the recovery system.
    • secured: same properties as signed plus it is mandatory for the device to use full disk encryption and secure boot.
  • serial-authority (optional) list of serial authorities. Use “generic” to have the snap store generate a serial.

  • classic (optional) is a flag that tells us if this is an all-snap system (false) or not (true). If not set, architecture, gadget, and kernel are mandatory. If set, kernel is forbidden and architecture and gadget are optional. If not present, an all-snap system is assumed.

  • store (optional) header specifies a particular branded virtual store to be used for this model. The store in question has custom content specific to that model, curated by that brand, and managed by the store owner or the relevant brand. Each model knows which store it needs to speak to in order to get the appropriate content. If left out the device defaults to use the main Ubuntu store.

  • snaps lists the snap package to include in the image. “pc”, “pc-kernel”, “core20” and “snapd” are all required for a functioning core20 device. Optional additional snaps can also be listed. It consists of the following keywords and mappings:

    • name (mandatory): name of the snap. Cross-checked at image build time but ignored later.
    • type (mandatory): type of the snap, needs to be either: base|gadget|kernel|app|core. app is the default.
    • id (optional): id of the snap if assigned by a store. Must be omitted for local snaps.
    • modes (optional): a list with UC20 modes (verbs, “run”) or mode aliases for which the snap needs to be installed (“ephemeral”, for recover and install modes).
      Default is [run] which should not be used for types kernel|gadget and for the snap indicated by the “base” header.
      For “recovery” and “install” modes, “ephemeral” can be used. This will install the snaps only while the system is in an ephemeral state (running from tmpfs). They will not be installed on ubuntu-data unless explicitly declared, such as with [run, ephemeral], although those snaps will still reside on ubuntu-seed.
    • presence (optional): set to mark a snap whose absence will not fail installation or recovery. Can be optional or required but defaults to required.
    • default-channel (optional): initial tracking channel for the snap, default is “latest/stable”.

This assertion is needed when creating an Ubuntu Core device image.

For instance, this is an Ubuntu Core model assertion based on ubuntu-core-20-amd64 :

{
    "type": "model",
    "series": "16",
    "authority-id": "developer-id",
    "brand-id": "developer-id",
    "model": "ubuntu-core-20-amd64",
    "architecture": "amd64",
    "timestamp": "2020-11-17T13:09:51+00:00",
    "base": "core20",
    "grade": "signed",
    "storage-safety": "prefer-encrypted",
    "snaps": [
        {
            "name": "pc",
            "type": "gadget",
            "default-channel": "20/stable",
            "id": "UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH"
        },
        {
            "name": "pc-kernel",
            "type": "kernel",
            "default-channel": "20/stable",
            "id": "pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza"
        },
        {
            "name": "core20",
            "type": "base",
            "default-channel": "latest/stable",
            "id": "DLqre5XGLbDqg9jPtiAhRRjDuPVa5X1q"
        },
        {
            "name": "snapd",
            "type": "snapd",
            "default-channel": "latest/stable",
            "id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4"
        },
        {
            "name": "htop",
            "type": "app",
            "default-channel": "latest/stable",
            "id": "hJmReLmgXSUj4SF7WhyTVRV6IzUa4QUZ"
        }
    ]
}

There should probably be mention of storage-safety key, since full disk encryption page mentions it as as settable in the Model assertion and links here.

Thanks for letting us know, and you’re right - storage-safety should have been described here too, which it now is.