Sign a model assertion

After a model has been created or modified, it must be signed with a GPG key to become a model assertion. This ensures the model cannot be altered without the key and also links the created image to both the signed version of the model and your Ubuntu One account.

This is accomplished in three stages:

1. Create a key

First make sure there are no keys already associated with your account by running the snapcraft list-keys command (you will only have a key if you’ve previously signed an assertion; if you already have a key, you can use that one):

$ snapcraft list-keys
No keys have been registered. See 'snapcraft register-key --help' to register a key.

Now use snapcraft to create a key called my-model-key (the name is arbitrary):

$ snapcraft create-key my-model-key
Passphrase: <passphrase>
Confirm passphrase: <passphrase>

As shown above, you will be asked for a passphrase. You need to remember this as you’ll be prompted to enter it whenever you use the key, including the very next step.


Rather than creating a key for every device, the same key is typically used across all models or model families.

2. Register the key

We now need to upload the key and register it with your Ubuntu One account. This is accomplished with register-key:

$ snapcraft register-key my-model-key
Enter your Ubuntu One e-mail address and password.
If you do not have an Ubuntu One account, you can create one at
Email: <Ubuntu-SSO-email-address>
Password: <Ubuntu-SSO-password>

Registering key ...
Done. The key "my-model-key" (<key fingerprint>) may be used to sign your assertions.

Regardless of whether you’re logged in with snapcraft, you will be asked for your account and password details. You’ll also need to unlock the key with your passphrase, and when the process is complete, the snapcraft list-keys command will now list the registered key:

$ snapcraft list-keys
    Name          SHA3-384 fingerprint
*   my-model-key  <key fingerprint>

Update the timestamp

As mentioned earlier, the timestamp in the model assertion must be set to a time and date after the creation of our key. This means we need to edit my-model.json to update the timestamp with the current time.

    "timestamp": "2022-04-04T10:40:41+00:00",

This is a UTC-formatted time and date value, used to denote the assertion’s creation time. It needs to be replaced with the current time and date, which can be generated with the following command:

$ date -Iseconds --utc

3. Sign the model

A model assertion is created by feeding the JSON file into the snap sign command with your recently-created key name and capturing the output in the corresponding model file:

snap sign -k my-model-key my-model.json > my-model.model

You will again be asked for your key’s passphrase.

The resultant my-model.model file contains the signed model assertion and can now be used to build the image.

gpg: signing failed:

If you encounter a gpg: signing failed error while signing your assertion from a non-desktop session, such as over SSH, run export GPG_TTY=$(tty) first.

The “snap sign” command does not need to read the JSON file from stdin; you can just specify the filename as a regular parameter these days. If you do not specify an input file, then, yes, the command reads from stdin by default.

1 Like

There is some ambiguity with snapcraft commands and the output of

$ snapcraft help --all

A number of snapcraft commands have both long and short forms:

$ snapcraft list-plugins
$ snapcraft plugins

That’s fine, but it’s confusing when a page like this refers to “snapcraft keys”, while the actual help output reads:

Store Key Management:
create-key: Create a key to sign assertions.
register-key: Register a key to sign assertions with the
Snap Store.
sign-build: Sign a built snap file and assert it using
the developer’s key
list-keys: List the keys available to sign assertions

Should settle on one form or the other, not jump back and forth between the two.

It seems that “snap sign” no longer needs the “-k” option in front of the key.

There is potential for confusion as you use “my-models” for the key name, and “my-model” for the model name. Guaranteed, someone is going to mix those up and come away baffled.

Thanks. I’ve replaced them with the long-form.

I think this is only true if you have a key named default (I just gave it a go).

Good point, thank you. I’ve updated the key name to make it less similar.

I definitely needed to add the “-k” option. It took me too long to hunt it down. Please add it to the instructions!

@jnugen I made the change. Thanks.

1 Like