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.