Skip to content

Update Manager uses the wrong destination for keyrings #1036

Description

@SineSwiper

Describe the bug
The "Add missing keys" button adds keys to /etc/apt/trusted.gpg.d/. This is wrong, because the keyrings have been moved to /usr/share/keyrings. The apt command does not look in /etc/apt/trusted.gpg.d/, so this button doesn't do anything useful.

Furthermore, this may impact other tools within Update Manager that interact with keyrings.

Screenshots

Image

To Reproduce

  1. Software Sources > Maintenance > Add missing keys
  2. ls -l /etc/apt/trusted.gpg.d/
  3. See keys updated in bad location

Expected behavior
Keys in /usr/share/keyrings

Distribution:
Linux Mint

Software version:
7.1.4

Logs:
Nothing relevant.

Activity

  1. darkowlzz commented on Apr 2, 2026

    @darkowlzz

    Hi, I spent some time trying to understand this issue, as I too was a bit confused by exactly the scenario reported in this issue and some other issues related to the new .sources (Deb822) source file format. I think I have a theory for what's happening in the scenario described in this particular issue, with a fix. Just wanted to share my findings here first before proposing the fix.

    Background

    Although this issue is reported in mintupdate (Update Manager) repository, the Software Sources program is in https://github.com/linuxmint/mintsources . The Update Manager has a menu option Edit > Software Sources, which opens the Software Sources (mintsources) application.
    Before spending so much time with mintsources and reading the source code, it wasn't obvious to me what the Maintenance > Add missing keys option was for. I believe it is meant for the scenarios where a new source repository is added (either in /etc/apt/sources.list.d/ or through the mintsources Additional Repositories > Add) and the corresponding signature verification keys are required to be able to use the repository. Usually, the third party repository docs describe the procedures for adding both the source list and the key. But the Maintenance > Add missing keys options just makes it easier. But there are some caveats when doing so which mintsources handles to some extent, and misses by no fault of it's own, but mostly because of the new Deb822 format, details below.

    Before describing my theory, I'd like to share my findings about the various relevant directories, as knowing them helps understand the observations:

    • /etc/apt/trusted.gpg.d/ - The keys placed in this directory are automatically trusted by apt. If a source file doesn't specify the path to the key (e.g.: signed-by=/usr/share/keyrings/steam.gpg is not defined), the keys in trusted.gpg.d/ directory will be used by apt to verify the source. This happens when the source is added from the mintsources GUI Additional Repositories > Add, if only the address of the repository, along with suite and components are provided (e.g.: deb https://repo.steampowered.com/steam/ stable steam). Because is it automatically trusted, it is discouraged to add third party repository verification keys in this. mintsources puts the key here when the source doesn't specify the path to the key.
    • /usr/share/keyrings/ - The keys placed in this directory are not automatically trusted by apt. This directory is recommended to be used by the package managers to install the keys and update them from time to time. Manual edits to the files in this directory can get overwritten by the package manager or OS updates. Most of the third party repositories document their keys to be added here. Their source also refer to signed-by file in this directory. Since this directory is not automatically trusted, only if the sources refer to the key file in this directory, they are used for verification. For example, in case of steam, deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steam forces apt to only attempt verification using the file /usr/share/keyrings/steam.gpg. If the file is missing, the verification would fail. But if the file is missing, mintsources' Maintenance > Add missing keys will download and put the file in /usr/share/keyrings/steam.gpg, as it is specified in the source file. Only when it's not specified, mintsources puts it in /etc/apt/trusted.gpg.d/ directory.
    • /etc/apt/keyrings/ - The keys placed in this directory are also not automatically trusted by apt. This directory is recommended to be used for any user managed keys that are expected to persist and not get overwritten by any updates. Similar to /usr/share/keyrings/, any source can refer to key files in this directory for verification. But unlike /usr/share/keyrings/ keys, the keys are not expected to be managed by the package manager or automatically updated. The system user/admin usually is responsible for updating the key. mintsources uses this directory temporarily when downloading the keys and later move them to the key path, if specified in the source, or under /etc/apt/trusted.gpg.d/.

    /usr/share/keyrings/ and /etc/apt/keyrings/ are generally recommended for adding keys. Usually, it's /usr/share/keyrings/ as the keys are managed by the package managers with the packages from the added repository.

    Observed bug

    Taking the example of steam, if https://repo.steampowered.com/steam/ is followed perfectly, the key is expected to exist in /usr/share/keyrings/steam.gpg, the source file refers to this file and verification should succeed. But if the source file doesn't contain signed-by=/usr/share/keyrings/steam.gpg, even if the key exists in /usr/share/keyrings/steam.gpg, it can't be use it to verify because /usr/share/keyrings/ directory is meant for explicit reference verification.
    On the other hand, if no key was created by the user and only the source was created but with a reference to the key under /usr/share/keyrings/, ideally, mintsources would place the downloaded key under /usr/share/keyrings/ and verification would succeed. But due to a bug, mintsources fails to find where it should put the key file, even when it is specified in the source file, and it defaults to adding the key in /etc/apt/trusted.gpg.d/. But since the source already has a reference to a key, it will not be verified with the trusted.gpg.d/ directory key.

    To be clear, mintsources adding the key in /etc/apt/trusted.gpg.d/ isn't wrong, but in the specific scenario where the source has a signed-by field referring to /usr/share/keyrings, key in /etc/apt/trusted.gpg.d/ won't be used.

    Debugging

    Reading the code and running the mintsources program, I wasn't able to reproduce this bug initially. I cloned the repository and ran the python script as root. Comparing the latest code in the git repository and Linux Mint 22.3, the mintSources.py content is exactly the same. But when I run the same program from the GUI, not in terminal with python, I was able to reproduce the bug. mintsources is installed as a symlink /usr/bin/mintsources -> software-sources, where the main program, mintSources.py is run in a subprocess.
    Adding some debug statements, and trying various things to understand why the downloaded key was being written to trusted directory instead of the one specified in signed-by directory, I noticed that mintsources uses inxi -r for listing the sources and extracts the key file path from there. The command inxi -r | grep {uri} (refer https://github.com/linuxmint/mintsources/blob/f57af383dc51682833a1774d7a75813f192a7fe1/usr/lib/linuxmint/mintSources/mintSources.py#L1217) seemed to be resulting in an empty result. Which leads to mintsource not knowing where to put the key and it defaults to writing it in the trusted directory.
    When the program is run in a terminal, I can see that the result of inxi-grep appears to be as expected and the key is written to /usr/share/keyring/ or the specified key path. After trying a few more things, I noticed a difference in inxi output when run in terminal and as a subprocess not from the terminal.

    When mintsources is run from GUI, inxi -r results in:

    Repos:
      12No active apt repos in /etc/apt/sources.list
      12Active apt repos in /etc/apt/sources.list.d/official-package-repositories.list
        121 deb https: //packages.linuxmint.com zena main upstream import backport
        122 deb https: //archive.ubuntu.com/ubuntu noble main restricted universe multiverse
        123 deb https: //archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse
        124 deb https: //archive.ubuntu.com/ubuntu noble-backports main restricted universe multiverse
        125 deb http: //security.ubuntu.com/ubuntu/ noble-security main restricted universe multiverse
      12Active apt repos in /etc/apt/sources.list.d/steam-stable.list
        121 deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https: //repo.steampowered.com/steam/ stable steam

    12 in each of the lines above is a color code, which can be ignored.
    When the same is run in a terminal, it results in:

    Repos:
      No active apt repos in: /etc/apt/sources.list
      Active apt repos in: /etc/apt/sources.list.d/official-package-repositories.list
        1: deb https://packages.linuxmint.com zena main upstream import backport
        2: deb https://archive.ubuntu.com/ubuntu noble main restricted universe multiverse
        3: deb https://archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse
        4: deb https://archive.ubuntu.com/ubuntu noble-backports main restricted universe multiverse
        5: deb http://security.ubuntu.com/ubuntu/ noble-security main restricted universe multiverse
      Active apt repos in: /etc/apt/sources.list.d/steam-stable.list
        1: deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steam

    with proper color in the terminal.
    The colors weren't the core issue. I tried adding -c 0 to inxi but the problem persisted. The problem was the repository address. For some reason, inxi would insert a space after http:. I suspect that maybe it interprets it as a key-value pair and tries to prettify the result, but not always. After going through the inxi man page, I tried the --tty option, https://man.archlinux.org/man/inxi.1#tty. It seems inxi does things differently by default, expecting that it's running in an IRC client.

    inxi --tty -r fixes the problem, grep successfully matches with the repository URL. mintsources writes the key in the path specified by signed-by in the source file.

    Here's a diff of the change:

    diff --git a/usr/lib/linuxmint/mintSources/mintSources.py b/usr/lib/linuxmint/mintSources/mintSources.py
    index ff9060f..da23b55 100755
    --- a/usr/lib/linuxmint/mintSources/mintSources.py
    +++ b/usr/lib/linuxmint/mintSources/mintSources.py
    @@ -1214,7 +1214,7 @@ class Application(object):
                 uri = repository.uri
                 if uri.endswith("/"):
                     uri = uri[:-1]
    -            output = subprocess.getoutput(f"inxi -r | grep {uri}")
    +            output = subprocess.getoutput(f"inxi --tty -r | grep {uri}")
                 key_path = None
                 if "signed-by" in output:
                     key_path = output.split("signed-by=")[1].split("]")[0]

    You can make a copy of the original file and add this little change to try it yourself. Even if there's an existing key in /etc/apt/trusted.gpg.d/, another key will be added in /usr/share/keyrings as per the source list's signed-by value.

    The Authentication Keys tab in mintsources depends on apt-key list for listing the keys, which seems to only list the keys under trusted.gpg and trusted.gpg.d/. Maybe this could be an improvement to add other existing keys.

    Another problem I noticed is that all the above applies to the old .lists sources files. The new .sources (Deb822 format) files are not supported for extracting the signed-by value because inxi doesn't seem to list that value in inxi -r output. Repositories like the Microsoft VSCode, Brave Browser, etc use the Deb822 format. I have no perl experience to look much into inxi's code, I tried a little. But maybe we can do all that in python itself using repolib which is already used for reading the sources.

  2. mtwebster commented on Sep 23, 2026

    @mtwebster
    Member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions