Assertions

An assertion is a digitally signed document that either verifies the validity of a process, as attested by the signer, or carries policy information, as formulated by the signer.

Snapcraft, snapd, the Snap Store and Brand stores all use assertions to handle a variety of functions and processes, including authentication, policy setting, identification and validation.

Assertions are text-based and take a context-dependent format that always includes one or more headers, an optional body, and the encoded signature.


Assertion types

These are the currently used assertion types:

  • account: links an account name to its identifier and other properties
  • account-key: holds the public part of a key belonging to the account
  • model: brand-specified properties for the device, used to drive the building of an Ubuntu Core image
  • serial: binds the device identity to the device’s key by carrying the public part
  • snap-build: the basic properties of a snap at the time it was built by the developer
  • snap-declaration: defines various snap properties, such as snap-id, its name, and the publisher, plus policy related to accessing privileged interfaces
  • snap-revision: store acknowledgement on receipt of a snap build labelled with a revision
  • store: defines the configuration needed to connect a device to a store
  • system-user: usually brand authorisation to create local system users on specified devices
  • validation: validates a specific snap revision for a given series
  • validation-set: a group of snaps that are either installed or permitted to be installed together

Assertion format

The typical format of an assertion, with common headers, is as follows:

type:          <type>       # For example, “account” or “model”
authority-id:  <account id> # On whose authority this assertion is made
<key field 1>: <value>      # Fields identifying the object of the assertion
...
<key field N>: <value>
<other field>: <value>
...
revision: <int>             # Assertions can be updated with a higher revision
format: <int>               # Assertion types can have backward incompatible format changes signaled by a higher format
body-length: <int>          # Present if a body is provided with this assertion
sign-key-sha3-384: <key id> # Encoded key id of signing key

<body>                      # Optional type-dependent body of length `body-length` bytes

<signature>                 # Encoded signature
  • every assertion has type, sign-key-sha3-384 and a signature
  • most assertions have authority-id
  • values are scalars (strings, integers, booleans), lists, or maps
  • some headers are used as a unique index to specify the context of an assertion of the given, together they form the so-called primary key of the assertion
  • most assertions also have a revision to enable a particular assertion to be updated by issuing another assertion of the same type and index with a higher revision.

Given a particular type and index, there is only one “latest” valid assertion that properly determines policy for a system - the one with the highest revision. For a given assertion, the index headers must all be defined.

Viewing assertions

The snap known <type> [<header>=<value>...] command can be used to view assertions or a specific type:

$ snap known account account-id=generic
type: account
authority-id: canonical
account-id: generic
display-name: Generic
timestamp: 2017-07-27T00:00:00.0Z
username: generic
validation: certified
sign-key-sha3-384: [...]

Similarly, a snap’s assertions are downloaded alongside the snap using the snap download command:

$ snap download gnome-calculator
Fetching snap "gnome-calculator"
Fetching assertions for "gnome-calculator"
Install the snap with:
   snap ack gnome-calculator_945.assert
   snap install gnome-calculator_945.snap

Encoded sha3-384 differences

Assertions include a snap-sha3-384 hash value to ensure their integrity:

snap-sha3-384: j73cFx0pIMoX4U[...]

However, these hash values will appear different, depending on whether they were either downloaded from the Snap Store, such as with the snap download command, or retrieved with via the snapd REST API.

This difference is because the Store uses hex-encoded byte arrays while the snapd REST API encodes hashes with with base64.

Developers can typically use hash-encoded values directly in their code, whereas base64 values will need to be decoded first, such as with the base64 command.

2 Likes

Can i extract a value from assertion with the key with the snap known ?? command ? For example i’ll use the Unique Id for the device from snap know serial ?serial?

Hi, can you be more specific about the information you are looking for? Also, try using the snap model command, as that will have the serial for your device in it.

Yep actually i’m using:

snap model
brand Genericâś“
model generic-classic
serial xxxx-c7da-xxxx-be04-xxxx

And parsing the string to get only the serial id! i’m asking if i can get only the serial id straight with one command to use it in node.js without parsing the returned string !

No, unfortunately using snap model and doing some string parsing is the “least amount of work” you can do today. We have some vague plans to add something like formatted output with JSON that may be closer to what you want, but for now something like snap model --serial or snap model is the closest you can get.

Thanks! Instead i’m using snap model --serial …

If I download a snap and its assertion file, and add the assertion to the system assertion DB with “snap ack”, can I later delete that assertion? Or would that be a meaningless action, in the sense that, once one validates an assertion, it would make no sense to subsequently withdraw that validation?

mostly this. OTOH assertions are revisioned, and newer revisions supersede older ones. Some assertions can be marked in a new revision as revoked or expired in type-specific ways by their issuer. This wouldn’t result in deletion though. snapd might start in the future to garbage collect some assertions that aren’t grounding active state though, for space reasons, this would be limited and automatic.

Was playing around with “snap known” to list particular assertion types, and noticed that snapd appears to recognize a number of assertion types (for one reason or another) that are not in the list on this page:

  • base-declaration
  • repair
  • snap-build
  • snap-developer
  • store
  • validation-set

I’m aware that “validation-set” is still a work in progress so it’s not “officially” supported, but should any of these be in the list of “currently supported assertion types” on this page? Are there others?

rday

P.S. The assertions reference page does mention some of the ones I listed, but not base-declaration, repair or snap-developer, so even the reference page seems incomplete.

This is an internal pseudo-assertion (it has a pseudo-signature “$builtin” and therefore cannot be transmitted between systems), it doesn’t actually appear via snap known, as it is not part of the system assertion database. It can be accessed via snap debug base-declaration, it collects and works as a convenience internal holder for base interface policy rules. Review-tools consumes it internally but in general we are not bound to its details.

This is used by the repair mechanism. There are forum posts from its implementation period. ATM only canonical can sign such assertions. I think it is in our backlog to document the mechanism in general to some extent.

Its support is incomplete, it is not used by the store and OTOH it doesn’t solve some of the related use cases as it is not detached from the main root of trust.

ATM this is an unsupported assertion.

This is used to describe both brand stores and proxy stores. It could be documented.

This should be documented.

Can more details be provided about the format these are in? Is that a hex encoded RSA key fingerprint? or something else? What is signature? Does sign everything above it? is it PGP encoded packet data? PEM encoded CMS signature? For example, what one should expect and use to parse and verify it by-hand / pen & paper?

CC: @pedronis