sources.list — Where Repository Definitions Live

Chapter 3
Managing Repositories on Debian-Based Systems
sources.list, adding third-party repositories safely, and how apt actually verifies what it downloads

Chapter 2's apt update refreshes the package list from somewhere — this chapter covers exactly where, how to add new sources beyond the defaults, and the verification mechanism that prevents apt from blindly trusting whatever a repository claims to offer.

sources.list — Where Repository Definitions Live

$ cat /etc/apt/sources.list
deb http://deb.debian.org/debian bookworm main contrib non-free
deb http://deb.debian.org/debian bookworm-updates main contrib non-free
deb http://security.debian.org/debian-security bookworm-security main contrib non-free
deb
Binary packages (deb-src would mean source packages instead)
http://deb.debian.org/debian
The repository's base URL
bookworm
The release codename — Debian 12 in this example; this is the part that changes between OS versions
main contrib non-free
Components — main (fully free software), contrib (free but depends on non-free), non-free (proprietary)

sources.list.d/ — The Modern, Preferred Location for Additions

Rather than editing the main sources.list file directly, individual .list files in /etc/apt/sources.list.d/ let each added repository live in its own file — easier to remove cleanly later, and exactly the convention modern package-provided install instructions (Docker, VS Code, and similar) typically use.

Adding a Third-Party Repository

$ # Modern approach — a dedicated file in sources.list.d/
$ echo "deb https://example.com/debian stable main" | sudo tee /etc/apt/sources.list.d/example.list
$ sudo apt update

How apt Verifies What It Downloads — GPG Keys

Without verification, apt would have no way to confirm a downloaded package genuinely came from the repository it claims to, or that it hasn't been tampered with in transit — exactly the kind of supply-chain risk this mechanism exists to prevent.

Repository signs packages with their private key apt verifies signature using the public key Trusted
apt only proceeds if the signature genuinely matches a public key it's been told to trust
$ # The modern, recommended way to add a repository's signing key
$ curl -fsSL https://example.com/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/example.gpg

$ # Reference that specific key in the repository's source entry
$ echo "deb [signed-by=/usr/share/keyrings/example.gpg] https://example.com/debian stable main" | sudo tee /etc/apt/sources.list.d/example.list
apt-key add is deprecated — signed-by is the modern replacement
Older tutorials commonly show sudo apt-key add key.gpg, which adds a key trusted system-wide for every repository — genuinely too broad, and deprecated as of recent Debian/Ubuntu versions specifically for that reason. The signed-by approach shown above scopes a key to exactly the one repository that needs it, which is the correct, current practice.

PPAs — Ubuntu's Personal Package Archives

$ # Ubuntu-specific convenience tool for adding a PPA
$ sudo add-apt-repository ppa:someuser/somerepo
$ sudo apt update

PPAs are an Ubuntu-specific convention (not available on plain Debian or Raspberry Pi OS without extra setup) — individually maintained repositories, often for software not yet packaged in the official repos, or for newer versions than the official ones carry. add-apt-repository handles both adding the source entry and the signing key in one step.

Adding a third-party repository means trusting that maintainer with root access to your system
Every package installed via apt typically runs install scripts with root privileges — a malicious or compromised third-party repository can run essentially anything on your machine. Only add repositories from sources you genuinely trust, and prefer official project-provided repositories over random PPAs or unofficial mirrors whenever possible.

Pinning — Controlling Which Repository Wins When Multiple Provide the Same Package

With multiple repositories configured, more than one might offer a package with the same name — APT pinning (/etc/apt/preferences.d/) lets you explicitly prioritise one source over another for specific packages, rather than relying purely on version-number comparison.

Chapter 3 Quick Reference

  • /etc/apt/sources.list — the main repository definition file; codename (e.g. bookworm) is the part that changes per release
  • /etc/apt/sources.list.d/ — the modern, preferred place to add individual repositories in their own file
  • GPG signing — verifies a package genuinely came from the claimed repository, unmodified
  • signed-by= in the source line — the modern, properly scoped replacement for deprecated apt-key add
  • PPAs — Ubuntu-specific personal repositories; add-apt-repository handles source + key in one step
  • Trusting a repository means trusting it with root access — only add sources you genuinely trust
  • Pinning — controls which repository wins when multiple provide the same package
  • Next chapter: dpkg deep dive — querying installed packages, package contents, manual install/repair