zakrok.dev

/* With managing of all the necessary pinentry requirements. */

Home manager GitHub GPG commit signing

Published on: 2024-12-16

Important! All of my configuration for NixOS is available on my personal GitHub repository.

Please refer to the commit with hash 8bebd5148d403ff1410a70e9271d02867fc9aa2e to get access to my complete config at the time of writing this blog post.

Verifying your commits in GitHub (and possibly other git hosting platforms) using a private GPG key can bring many benefits (one of which, of course, being style points!) Since NixOS is already abundant in bringing said style points, it comes in with some issues and difference in management compared to other Linux distributions. In this tutorial we will go over how we can set up GPG signing of our commits using home-manager on our NixOS device.

Creating a GPG on NixOS

When I first tried to do this, I did not have gpg on my computer, so I added it by adding the gnupg package to my configuration:

# I chose to add it to my system packages on the entire host because 
# it is something I believe should be present anywhere.
environment.systemPackages = with pkgs; [
    ...
    gnupg
    ...
];

This will let you use the gpg command. The GitHub tutorial on generating a GPG key gives concrete steps on how to create one. Naturally, I followed the precisely but ended up with this error:

gpg: agent_genkey failed: No pinentry
Key generation failed: No pinentry

This is an error related to pinentry. After several checks I finally found a solution posted by kiarie404 posted on the NixOS discussion forums.

Appending the flag --pinentry-mode loopback was just enough for me to get it running and produce me a GPG key. Please refer to the GitHub tutorial mentioned above to see which options are compatible with GitHub. Mine in particular were:

gpg --full-generate-key --pinentry-mode loopback

After this, use the listing command to get all of your keys. This way, we will see the uuid of our recently generated key:

gpg --list-secret-keys --keyid-format=long

Probably, your return will look like this:

------------------------------------
sec   4096R/IVNV4948F... 2025-04-11 
uid                          ... <...@email.com>
ssb   4096R/332GG44G... 2025-04-11

The uuid for your key is the string located just after 4096R/. In case you did not use RSA, this will be after the first slash on the sec row.

Use it to export your key content. If you are using / have xclip on your device you can even directly copy it to your clipboard:

gpg --armor --export IVNV4948F...

# append this pipe to get it to your clipboard
gpg --armor --export IVNV4948F... | xclip -sel clip

Finally, go to your GitHub profile keys settings page and add the GPG key (it should be the second table of keys, just below the SSG ones).

Using the key to sign your commits.

Here comes the funny part. So far we have been using primarily imperative actions to generate and add our key. However, now we need to tell our git that we would like to have all of our future commits signed by our key declaratively in our home-manager config.

The tutorials available online give you insight in the git configuration you need to have in order to achieve this goal. These involve setting the user.name and user.email in a global config and specifying the key that should be used for signing. All of this can be done using home-manager:

# git config options
programs = {
    git = {
        enable=true;                          # enable home manager config of git
        userName = "Zakrok09";
        userEmail = "31936449+Zakrok09@users.noreply.github.com";

        extraConfig = {
            commit.gpgsign = true;            # forcing each commit to be gpg signed
            tag.gpgSign = true;               
            user.signingkey = "IVNV4948F..."; # the uuid of your key that you got earlier
        };
    };
};

# gnupg
services = {
    gnome-keyring.enable = true;
    gpg-agent = {
        enable = true;
        defaultCacheTtl = 1800;
        enableSshSupport = true;
    };
};
programs.gpg.enable = true;

Rebuild and switch your home-manager after these changes.

When you are done, try commiting some changes to a repository and pushing them to GitHub. If you added your GPG key and did the rest of the steps, it should appear as “Verified” with a cool little checkmark. Congratz!

If you are experiencing problems, please make sure e.g. that there are no local overrides of the global config in your opened repository that you used to test.

Issues with configuration not applying globally

When I was figuring this out, I ran into some issues where my git configuration i specified in my home-manager was not applying, and instead I got the username and email of some old git config --global commands I ran. To fix this, check the file in your home folder called ~/.gitconfig. This is where my configs went when I tried to apply them imperatively. Delete this file and rebuild and switch your home-manager config.

Final remarks

In case you find anything wrongful with this explanation, please contact me at contact@zakrok.dev.