Assertions

Assertions are digitally signed documents that express a fact or policy by a particular authority about a particular object in the snap universe. An assertion consists of a set of structured headers, which vary based on the type of assertion, an optional body (UTF8 text, with format depending on type of assertion) and the signature.

Assertions are intended to be understandable by human inspection, although full validation requires the use of provided tooling.

Assertions are the way trust information is transmitted between the different parts of the snap ecosystem (snapd daemon, snapcraft tool, store...). They are used for things like stating who is the publisher of a snap or who created a device image, or for allowing to do some actions if the right assertion is provided (like creating a system user).

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
revision:      <int>        # Assertions can be updated with a higher revision
<key field 1>: <value>      # Fields identifying the object of the assertion
...
<key field N>: <value>
<other field>: <value>
...
sign-key-sha3-384: <key id> # Encoded key id of signing key

<body>                      # Optional type-dependent body

<signature>                 # Encoded signature

Every assertion will have a type and sign-key-sha3-384, as well as a signature, and most will have an authority-id. Values may be scalars (strings, integers, booleans), lists, or maps. Some of the headers play the role of an index, which uniquely specifies the context of this assertion given the type. Most assertions will also have a revision which enables 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.

Some headers contain identifiers of one type or another. These ids are formed by a sequence of 32 random characters taken out of an alphabet of 62 characters (uppercase letters + lowercase letters + numbers). However, in some cases the identifier is a fixed name like "canonical". This only happens in special cases.

When headers are defined as UTC date/time, the format that is needed is the same as the one generated by the command.

date -Iseconds --utc

It can be instructive to learn about the assertions that are stored in a system. You can find out with the command

snap known <assertion type>

Additionally, you can download the assertions associated to snaps in the store with the command

snap download <snap name>

which will download the snap and a file with its assertions. The file will contain account-key of the snap owner, snap-declaration, and snap-revision assertions.

Although in most cases assertions are generated automatically by the different parts of the system, it is worth noting that they can be generated manually with the snap sign command. The input must have a json format, for instance

$ cat account.json
{
    "type": "account",
    "authority-id": "234njDFJHG0jkh0asdAGQ43SESwerrfg",
    "revision": "14",
    "account-id": "asdfv389h4SSEDB49hasdfh8hfajhfak",
    "display-name": "John Smith",
    "username": "jsmith",
    "validation": "unproven",
    "timestamp": "2017-02-20T10:23:51+00:00"
}

can be signed by doing

$ cat account.json | snap sign > account

(we would be signing with our default key).

The output would be similar to:

$ cat account
type: account
authority-id: 234njDFJHG0jkh0asdAGQ43SESwerrfg
revision: 14
account-id: asdfv389h4SSEDB49hasdfh8hfajhfak
display-name: John Smith
timestamp: 2017-02-20T10:23:51+00:00
username: jsmith
validation: unproven
sign-key-sha3-384: Ix2EqDXjEdsY8yZACzvpc-3J1C022LPnHTP29fdpaWfOuTr8dG6Bva2qlm3ftn9b

AcLBXAQAAQoABgUCWKwrggAKCRAr48PRDeXDupqkEACnHhKv0DLqApeyzsr6sImgMfZ3+j7pxUz3
7NWk/0Ld/RzimlOavKitxi3wHPfb2Tw6kTI/faO3s+E3+Uq4/luzLILZ5CAOczqQAuPgAdphlHMx
gJCdFrOlw9quF4MtWJpXNa05OJsDm2G+B3GehJzReQ6vXriNjqTe/OmLrSpMPp7NoZb3nGcrNwWo
KULfveCgNRwl61vU3EfHif8qo1rlX0l4mxOp5w9GDhuZQZ8l+bJW9vBpGXmnEDYfsdbO2gCNykbV
CM+nkza/QdoAaBOiz2E/PFyipamRpv0ATo/RSePKTp9iUbOl1xNOiJBwc5+pUb6s3sDyzFNWIDBK
mN2J7tu2pO3yYTqR/DQs8eY+MkqGnBEK8KuKzfe87Nszrrd+ulBliYepkmk3xfrhJGLHN1qebZ2K
9ykYR8m2uoE5c2r40toaf6tay0QlddZq9aq6FvdnnA6CArbsdwbXZuMv780MmwnIFJk2D4p0+5mM
SbSU63kiSJ+oQRKmHZ7jryP06kvzfYmSwT7LXjvu0qLx7ac+OoMiCyFzXcwGfvM9KzZW71fMTfvI
fmuDl+fSm0edz1QURcamr4WmwlNI+yebPfrhZAWXvvfk/sXT2N12ojxp4M3DnO+1WVFHKaWyeS0G
eoyPdPAWyOm5KcTm3O92Q/jo3TQF5tyDMIHHOLnkUQ==

Below we define in detail the currently supported assertions. Unless otherwise noted, all fields are madatory.