Skip to content
academia.sh

Lesson 19 / 20

Repository Configuration

The components of a repository definition, the chain of trust formed by a signed index and package checksums, verifying a key's fingerprint, and the consequences of repository priority.

Contents

The previous two lessons said packages come “from the repository” but never defined what a repository is. A repository is not just a file server; if it were, nothing would say the downloaded package is the right package.

This lesson covers the repository’s structure and the chain of trust built on it. The chain is the combination of the checksum verification from the file transfer lesson and the fingerprint confirmation from the encrypted shell lesson; the two meet here in a single mechanism.

Repository Definition

Introducing a repository to the system means giving it at least this information:

Field Meaning
Address The base location the files are downloaded from
Release Which version branch the repository offers
Component A subsection within the repository (for example, the free-software split)
Architecture Which processor family packages will be requested for
Key The public key that will verify the repository’s signatures

Definitions are kept under /etc, following the “configuration lives in text files” principle from the directory hierarchy lesson. Naming and syntax vary by package manager family; the fields do not.

A consequence of the address field is that the same content can be served from more than one server: mirrors. A mirror is an independent server carrying an exact copy of the repository, used to speed up downloads. Verifying a mirror’s content is the reason the chain below exists; otherwise each mirror would have to be trusted separately.

The Chain of Trust

A repository serves two kinds of file: the packages themselves, and an index file. The index carries every package’s name, version, dependencies, and content checksum. The index file itself is signed.

The chain has three links:

  1. The public key represents the identity of the party running the repository, and is introduced to the system once.
  2. The index file’s signature is verified with this key; if the signature is valid, the index’s content has not been altered.
  3. Every downloaded package’s checksum is compared against the value in the index; if they match, the package has not been altered.

A single signature indirectly covers thousands of packages. Packages do not need to be signed individually; it is enough that their checksums sit in a signed file.

The chain can be built and verified at small scale. The repository below consists of two packages, an index file, the index’s signature, and the repository’s public key:

$ ls
INDEX  INDEX.asc  plot-2.0.pkg  repo-key.asc  report-1.4.pkg

Introducing the Key

The first step is examining the key. A key’s identity is represented by its fingerprint, a fixed-length checksum:

$ gpg --show-keys --with-fingerprint repo-key.asc
gpg: directory '/home/student/.gnupg' created
gpg: keybox '/home/student/.gnupg/pubring.kbx' created
pub   ed25519 2026-07-26 [SC]
      E31E 9629 AEBE 63E9 0EEB  EDEE A258 E130 F14C ACAA
uid                      Repo Maintainer <maintainer@example>

There is a critical step here, and skipping it renders the whole chain meaningless: the fingerprint must be compared against a source independent of the channel the key was downloaded through. Downloading the key from the repository itself and verifying it against the fingerprint the same repository states verifies nothing.

The same problem existed with the server fingerprint in the encrypted shell lesson, and the solution is the same: identity is confirmed through a different channel on first contact, and any change afterward is caught automatically.

Once confirmed, the key is imported into the system:

$ gpg --import repo-key.asc
gpg: /home/student/.gnupg/trustdb.gpg: trustdb created
gpg: key A258E130F14CACAA: public key "Repo Maintainer <maintainer@example>" imported
gpg: Total number processed: 1
gpg:               imported: 1

Verifying the Chain

The index’s signature is tested with the key:

$ gpg --verify INDEX.asc INDEX
gpg: Signature made Sun Jul 26 19:37:53 2026 UTC
gpg:                using EDDSA key E31E9629AEBE63E90EEBEDEEA258E130F14CACAA
gpg: Good signature from "Repo Maintainer <maintainer@example>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: E31E 9629 AEBE 63E9 0EEB  EDEE A258 E130 F14C ACAA

The two lines say separate things and should not be confused. “Good signature” reports that the file was signed with this key and has not changed since — a mathematical verification. The warning says there is no proof the key’s owner is really who they claim to be; this means the independent-channel confirmation above was not done. The signature is valid, but who it belongs to is a separate question.

Once the index is verified, package checksums are tested:

$ cat INDEX
3375dab7d8aa59a185e9e8f5e0f4095517d89bdb75245ef22a25966e2e348756  plot-2.0.pkg
3fe6fac9c36f99b284199580aead74c6c2d33f3a60449954c90dac700ca48e08  report-1.4.pkg
$ sha256sum -c INDEX
plot-2.0.pkg: OK
report-1.4.pkg: OK

The chain is complete: the signature guarantees the index, the index guarantees the packages.

What the Chain Catches

If the package file is changed in transit, the checksum stops matching:

$ printf 'malicious content\n' > plot-2.0.pkg
$ sha256sum -c INDEX
plot-2.0.pkg: FAILED
report-1.4.pkg: OK
sha256sum: WARNING: 1 computed checksum did NOT match

To get past this, an attacker must also change the index. Once checksums are recomputed, the index becomes internally consistent again:

$ sha256sum *.pkg > INDEX
$ sha256sum -c INDEX
plot-2.0.pkg: OK
report-1.4.pkg: OK

But the signature no longer matches:

$ gpg --verify INDEX.asc INDEX
gpg: Signature made Sun Jul 26 19:37:53 2026 UTC
gpg:                using EDDSA key E31E9629AEBE63E90EEBEDEEA258E130F14CACAA
gpg: BAD signature from "Repo Maintainer <maintainer@example>" [unknown]

This is where the chain’s strength lies: changing the index requires the signing key, and that key sits not in the repository but with the maintainer. So compromising a mirror is not enough to alter the packages.

This is a guarantee transport-layer encryption cannot provide. An encrypted download shows the data did not change in transit; it does not show the content on the server was the correct content. A signature verifies the content’s origin, and having passed through mirrors does not change that. The two protections do not substitute for each other.

Adding a Repository Is a Trust Decision

Adding a new repository to the system means granting its maintainer the following: the ability to install packages on the system, the ability to run install scripts with root privilege, and the ability to replace existing packages with their own versions.

The last item is the least noticed. If a new repository offers a package with the same name as one in the system repository but a higher version number, that package takes the system package’s place on upgrade. For this reason package managers offer a priority mechanism: each repository is given a weight, and which source the same package is taken from is decided by that weight.

In practice, three criteria are followed.

The number of repositories is kept low. Every extra repository adds a party that must be trusted.

Extra repositories’ scope is narrowed. Only the packages actually needed being taken from that repository is ensured through priority rules or package-name restrictions.

Keys are kept separate per repository. Treating a single key as valid for all repositories turns compromising one key into compromising every repository.

If only a few packages are needed from a repository, downloading the package files and verifying them against their checksums leaves a narrower trust surface than adding the whole repository. The cost is that updates do not arrive automatically.

Summary

  • A repository definition consists of an address, release, component, architecture, and verification key.
  • Alongside packages, a repository serves an index file carrying package checksums, and this file is signed.
  • The chain of trust has three links: the key verifies the maintainer, the signature verifies the index, the checksums in the index verify the packages.
  • A key’s fingerprint must be confirmed through a source independent of the channel it came from; otherwise the chain verifies itself.
  • A valid signature shows a file has not changed; who the key belongs to is a separate question, and the warning line reports that.
  • Transport encryption shows data did not change in transit; a signature verifies the content’s origin; the two do not substitute for each other.

Next Step

The system has been surveyed, files organized, permissions established, and a path to installing software opened. One gap remains: how are the script and configuration files created in this course edited without leaving the terminal? The course’s last lesson covers terminal text editors — modal and modeless designs — and shows which one to choose under which conditions.

To keep your progress and take notes, Log in

My notes

Log in to take notes.

Start typing to search.

↑↓ Esc navigate · open · close