Description
APT trusts the keyrings in /etc/apt/trusted.gpg.d/, /etc/apt/keyrings/,
/usr/share/keyrings/ (and the legacy /etc/apt/trusted.gpg), and downloads from the
repositories listed in /etc/apt/sources.list and /etc/apt/sources.list.d/. These
directories should be root:root mode 0755 and their files root:root mode 0644 or
stricter.
/usr/share/keyrings/ also holds the Ubuntu Pro keys (ubuntu-pro-*.gpg) used by the ESM
repositories. /etc/apt/keyrings/ does not exist on 20.04 (not applicable until created). The
check follows symbolic links and checks their target.
Rationale
A user able to add a key or a source entry can make APT install a package of their choice, with
maintainer scripts running as root, at the next update. Only root may change them. Reading them
is harmless: keys are public and APT's unprivileged _apt user needs to read them.
Impact
None known. Ubuntu ships these files with these permissions.
Setting
| Location | /etc/apt/trusted.gpg.d, /etc/apt/keyrings, /usr/share/keyrings, /etc/apt/sources.list, /etc/apt/sources.list.d |
| Default | root:root, 0755 for directories and 0644 for files |
| Recommended | root:root, 0755 or stricter for directories, 0644 or stricter for files |
Audit
stat -c '%U:%G %a %n' /etc/apt/trusted.gpg.d /etc/apt/keyrings /usr/share/keyrings /etc/apt/sources.list.dshowsroot:rootand755or stricter.stat -L -c '%U:%G %a %n' /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d/* /etc/apt/keyrings/* /usr/share/keyrings/* /etc/apt/sources.list /etc/apt/sources.list.d/*showsroot:rootand644or stricter for every existing file.
Automated: every check must pass. Scanners report each check by its id.
trusted-gpg-d
The /etc/apt/trusted.gpg.d directory.
path: /etc/apt/trusted.gpg.d
owner: root
group: root
mode: '0755'
etc-keyrings
The /etc/apt/keyrings directory.
path: /etc/apt/keyrings
owner: root
group: root
mode: '0755'
usr-share-keyrings
The /usr/share/keyrings directory.
path: /usr/share/keyrings
owner: root
group: root
mode: '0755'
key-files
Every keyring file APT can use, following symbolic links.
script: |
d="/etc/apt/trusted.gpg /etc/apt/trusted.gpg.d /etc/apt/keyrings /usr/share/keyrings"
# shellcheck disable=SC2086
bad=$(find -L $d -maxdepth 1 -type f \( ! -user root -o ! -group root -o -perm /7133 \) \
-exec stat -L -c '%n %U:%G %a' {} + 2>/dev/null)
if [ -n "$bad" ]; then
printf '%s\n' "$bad"
exit 1
fi
# shellcheck disable=SC2086
echo "$(find -L $d -maxdepth 1 -type f 2>/dev/null | wc -l) key files root:root 644 or stricter"
sources-list
The /etc/apt/sources.list file.
path: /etc/apt/sources.list
owner: root
group: root
mode: '0644'
sources-list-d
The /etc/apt/sources.list.d directory.
path: /etc/apt/sources.list.d
owner: root
group: root
mode: '0755'
sources-list-d-files
Files in /etc/apt/sources.list.d.
path: /etc/apt/sources.list.d/*
owner: root
group: root
mode: '0644'
Remediation
chown root:root /etc/apt/trusted.gpg.d /etc/apt/keyrings /usr/share/keyrings /etc/apt/sources.list.dandchmod go-won them.- For each key file and source file:
chown root:root <file>andchmod 644 <file>(or stricter).
| Restart | none |
| Disruption | none |
Rollback
Restore the previous owner and mode with chown and chmod. Nothing else depends on them.
trusted-gpg-d
Generated from check trusted-gpg-d: the engine writes the fix for every output, it sets the expected value and the check runs again after.
etc-keyrings
Generated from check etc-keyrings: the engine writes the fix for every output, it sets the expected value and the check runs again after.
usr-share-keyrings
Generated from check usr-share-keyrings: the engine writes the fix for every output, it sets the expected value and the check runs again after.
key-files
find -L /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d /etc/apt/keyrings /usr/share/keyrings \
-maxdepth 1 -type f \( ! -user root -o ! -group root -o -perm /7133 \) 2>/dev/null |
while IFS= read -r f; do
chown root:root "$f" && chmod u-xs,go-wxs,o-t "$f" || exit 1
done
sources-list
Generated from check sources-list: the engine writes the fix for every output, it sets the expected value and the check runs again after.
sources-list-d
Generated from check sources-list-d: the engine writes the fix for every output, it sets the expected value and the check runs again after.
sources-list-d-files
Generated from check sources-list-d-files: the engine writes the fix for every output, it sets the expected value and the check runs again after.
Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.
References
- apt-secure(8), Ubuntu manual pages Canonical, vendor-doc, accessed 2026-10-19
- sources.list(5), Ubuntu manual pages Canonical, vendor-doc, accessed 2026-10-19
- Ubuntu Server documentation - Third-party repository usage Canonical, vendor-doc, accessed 2026-10-19
Mappings
| Framework | ID | Relation |
|---|---|---|
| NIST SP 800-53 Rev. 55.1.1 | CM-5 | related |
| NIST SP 800-53 Rev. 55.1.1 | AC-3 | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
Related controls
- related
CB-UBU-PKG-005Restrict access to APT repository credentials
People and lifecycle
| Authors |
|
| Verified | 2026-10-19 by Sn0wAlice on 20.04, Proxmox VM, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic. Passes on stock; world-writable keyring and 0777 sources.list.d detected and fixed. |
| Verified | 2026-10-19 by Sn0wAlice on 22.04, Proxmox VM, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic. Passes on stock; world-writable keyring and 0777 sources.list.d detected and fixed. |
| Verified | 2026-10-19 by Sn0wAlice on 24.04, Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic. Passes on stock; world-writable keyring and 0777 sources.list.d detected and fixed. |
| Verified | 2026-10-19 by Sn0wAlice on 26.04, Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic. Passes on stock; world-writable keyring and 0777 sources.list.d detected and fixed. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-19, 2026-10-19 |
| Translations | fr |