Home / Alt manpages / addgnupghome(8)

  • addgnupghome(8)
  • Admin command
  • linux

Create Missing GnuPG Homes Safely with addgnupghome

A new account needs a working .gnupg directory, and addgnupghome saves you hand-copying files into every home yourself. It creates a missing directory for one or more accounts, seeds it from /etc/skel/.gnupg, and leaves anything that already exists alone. Allow about five minutes for a normal setup.

You need the gnupg-utils package, a root shell or sudo, the target accounts, and a prepared /etc/skel/.gnupg directory. This guide describes the installed Ubuntu package version gnupg-utils 2.4.4-2ubuntu17.6, whose command identifies itself as GnuPG 2.4.4.

Before you start: what actually changes

addgnupghome is a small administrative shell script. For each account it looks up the home directory, creates $HOME/.gnupg only when that directory is absent, and copies the files and directories found in /etc/skel/.gnupg, excluding anything ending in ~. The new directory and copied entries are assigned to the target user and group, and the script sets a restrictive 0077 umask while it works.

There is no option for a different skeleton directory, home directory or destination. The syntax is a plain list of account names, not arbitrary paths:

addgnupghome ACCOUNT...

Run it as root: it needs to create directories in other users' homes and change their ownership. It is not a repair tool: an existing GnuPG home is deliberately left alone, even if its contents are incomplete.

1. Check the package and skeleton

These checks do not change anything:

command -v addgnupghome
dpkg-query -W gnupg-utils
sudo find /etc/skel/.gnupg -maxdepth 2 -print

On this installation the package reports gnupg-utils 2.4.4-2ubuntu17.6. The last command must list /etc/skel/.gnupg and the files or directories you intend to seed. If the directory is absent, the program stops before touching any account, with this error:

addgnupghome: skeleton directory `/etc/skel/.gnupg' does not exist

Do not build a skeleton by copying an arbitrary user's private GnuPG home: the skeleton is a system-wide template, and anything placed there gets copied into every account you name.

2. Check the target accounts

Confirm the account names and their home directories before invoking the command:

getent passwd alice bob
getent passwd alice | cut -d: -f1,6
getent passwd bob | cut -d: -f1,6

Replace alice and bob with real account names. Each account must exist, and its home directory must already be a directory; a missing account, missing home or failed ownership operation is reported on standard error and contributes to a non-zero exit status.

Check for an existing GnuPG home too, since the command skips it rather than adding files to it:

for account in alice bob; do
    home=$(getent passwd "$account" | cut -d: -f6)
    printf '%s: ' "$account"
    if [ -d "$home/.gnupg" ]; then
        printf 'already exists\n'
    else
        printf 'will be created at %s/.gnupg\n' "$home"
    fi
done

3. Create the missing directories

Warning

This changes account configuration and copies GnuPG-related files, with no confirmation prompt. Review the account list and skeleton contents immediately before running it.

sudo addgnupghome alice bob

Successful creation writes progress messages to standard error, such as:

addgnupghome: creating home directory `/home/alice/.gnupg' for `alice'
addgnupghome: skipping user `bob': `.gnupg' already exists

A skip is success for that account, not evidence that files were copied. The command can carry on processing later accounts after an individual error, then return a non-zero status, so capture it if this is part of a script:

if sudo addgnupghome alice bob; then
    echo "all requested accounts completed"
else
    status=$?
    printf 'addgnupghome failed with status %s\n' "$status" >&2
    exit "$status"
fi

4. Verify ownership, mode and contents

For each account that was meant to receive a new directory, inspect the result as root:

sudo stat -c '%n owner=%U group=%G mode=%a' /home/alice/.gnupg
sudo find /home/alice/.gnupg -maxdepth 2 -printf '%M %u:%g %p\n' | sort

The owner should be alice, the group should match the account's primary group, and the directory should not be readable by other users. The script uses a 0077 umask for files it creates, but the mode of a source file still carries over when copied, so check the actual result rather than assuming a mode.

Confirm GnuPG can use the new home without changing keys or contacting a service:

sudo -u alice gpg --homedir /home/alice/.gnupg --list-keys

An empty key listing is normal for a freshly seeded directory. What matters here is that the command runs, the home is accessible to alice, and the expected template files are present.

Common traps and recovery

  • Existing directory: a message saying .gnupg already exists means nothing was merged. Inspect that directory separately; if it needs repair, back it up and use a deliberate migration plan rather than deleting it just to make addgnupghome run.
  • Wrong account name: the command accepts account names resolved through the system account database, not a home path such as /home/alice. Use getent passwd to check spelling.
  • Missing skeleton: populate /etc/skel/.gnupg with files approved by the system administrator, then rerun the read-only checks; a failed run caused by a missing skeleton does not create target directories.
  • Partial failure: inspect the output and each named home. If a new directory was created but copying or ownership failed, stop and preserve evidence before repairing it.

Destructive action

To undo only a directory this run created, first verify the exact path and that it holds no user-created keys or configuration, then remove it as root:

sudo rm -rf -- /home/alice/.gnupg

This cannot be undone from the filesystem. Restore from a backup if the directory held data, or leave it in place and repair ownership and contents manually. Never run that command with an unreviewed variable or a broad path.

Done means

  • The skeleton was clean. It existed before the run and held only approved template data.
  • Every account was checked. Each named account and home directory was confirmed first.
  • Only missing homes were touched. New directories were created only for accounts without an existing .gnupg.
  • Ownership is correct. stat shows the expected user, group and restrictive mode.
  • GnuPG works there. A final gpg --list-keys check runs as the target user.
  • Nothing failed silently. Any non-zero exit status or partial result was investigated before the account uses GnuPG.