As we saw above, Guix ensures the source code it pulls from channels comes from authorized developers. As a channel author, you need to specify the list of authorized developers in the .guix-authorizations file in the channel’s Git repository. The authentication rule is simple: each commit must be signed by a key listed in the .guix-authorizations file of its parent commit(s)10 The .guix-authorizations file looks like this:
;; Example '.guix-authorizations' file. (authorizations (version 0) ;current file format version (("AD17 A21E F8AE D8F1 CC02 DBD9 F8AE D8F1 765C 61E3" (name "alice")) ("2A39 3FFF 68F4 EF7A 3D29 12AF 68F4 EF7A 22FB B2D5" (name "bob")) ("CABB A931 C0FF EEC6 900D 0CFB 090B 1199 3D9A EBB5" (name "charlie"))))
Each fingerprint is followed by optional key/value pairs, as in the example above. Currently these key/value pairs are ignored.
This authentication rule creates a chicken-and-egg issue: how do we authenticate the first commit? Related to that: how do we deal with channels whose repository history contains unsigned commits and lack .guix-authorizations? And how do we fork existing channels?
Channel introductions answer these questions by describing the first
commit of a channel that should be authenticated. The first time a
channel is fetched with
guix pull or
time-machine, the command looks up the introductory commit and verifies
that it is signed by the specified OpenPGP key. From then on, it
authenticates commits according to the rule above.
Additionally, your channel must provide all the OpenPGP keys that were
ever mentioned in .guix-authorizations, stored as .key
files, which can be either binary or “ASCII-armored”. By default,
those .key files are searched for in the branch named
keyring but you can specify a different branch name in
.guix-channel like so:
(channel (version 0) (keyring-reference "my-keyring-branch"))
To summarize, as the author of a channel, there are three things you have to do to allow users to authenticate your code:
gpg --exportand store them in .key files, by default in a branch named
keyring(we recommend making it an orphan branch).
Before pushing to your public Git repository, you can run
git-authenticate to verify that you did sign all the commits you are
about to push with an authorized key:
guix git authenticate commit signer
where commit and signer are your channel introduction. See Invoking guix git authenticate, for details.
Publishing a signed channel requires discipline: any mistake, such as an unsigned commit or a commit signed by an unauthorized key, will prevent users from pulling from your channel—well, that’s the whole point of authentication! Pay attention to merges in particular: merge commits are considered authentic if and only if they are signed by a key present in the .guix-authorizations file of both branches.
Git commits form a directed acyclic graph (DAG). Each commit can have zero or more parents; “regular” commits have one parent and merge commits have two parent commits. Read Git for Computer Scientists for a great overview.