Store APT Repository Credentials in auth.conf Safely

A repository password in /etc/apt/sources.list is one stray cat away from anyone who can read that file; apt_auth.conf(5) locks it down instead. By the end of this guide APT will read the username and password from a separate, permission-restricted file. The examples use a made-up host and credentials, so replace them before use.

Prerequisites: APT and a source entry that needs authentication. You need elevated privileges to write under /etc/apt. Allow about 10 minutes, including a dry check of the permissions and the source URL.

1. Inspect the installed APT version

The local manpage used for this guide documents APT 2.8.3. Check the version on the machine you are changing:

apt-get --version | sed -n '1,3p'

Checkpoint: the first line should identify the installed APT release. The syntax below is the apt_auth.conf(5) format. Basic support exists much earlier, but behaviour and documentation changed around APT 1.5, so do not assume every old client has identical matching rules.

2. Confirm the source host and path

Read the source entry that needs credentials. This is an ordinary, non-destructive command:

grep -R --line-number --include='*.list' --include='*.sources' \
  'https://packages.example.invalid/' /etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null

Replace packages.example.invalid with the real host. Record the scheme, hostname, optional port and path. The auth entry is matched against the URI APT needs, not against a repository nickname.

Checkpoint: for a source such as https://packages.example.invalid/debian bookworm main, the useful machine key is packages.example.invalid or a path beginning /debian.

3. Create a separate auth file

Use the fragment directory for one repository or service. The command below requires root and creates a new file; do not overwrite an existing file without inspecting it first.

sudo test ! -e /etc/apt/auth.conf.d/example.conf && \
sudo install --mode=600 /dev/null /etc/apt/auth.conf.d/example.conf

If that command reports that the file exists, stop and inspect it:

sudo sed -n '1,80p' /etc/apt/auth.conf.d/example.conf

Warning: the next command writes a password into the file. Use a password or token intended for APT, with the least access the repository supports. A token in a shell command can enter shell history or process observations, so the example uses an editor. Elevated command:

sudoedit /etc/apt/auth.conf.d/example.conf

Enter one block like this:

machine packages.example.invalid/debian
login REPLACE_WITH_USERNAME
password REPLACE_WITH_TOKEN

APT accepts the three recognised tokens machine, login and password. Tokens can be separated by spaces, tabs or newlines. Unknown tokens are ignored, so a misspelling can fail quietly.

Checkpoint: verify ownership and mode, without printing the secret:

sudo stat -c '%A %U:%G %n' /etc/apt/auth.conf.d/example.conf

Expect a mode beginning -rw-------, normally owned by root:root. If the mode is broader, repair it with sudo chmod 600 /etc/apt/auth.conf.d/example.conf.

4. Choose the narrowest machine match

A host-only entry matches every port for that host, while a port-specific entry matches only that port. A path makes the match narrower: the requested URI path must start with the path in the machine token.

# All HTTPS repositories on this host
machine packages.example.invalid
login REPLACE_WITH_USERNAME
password REPLACE_WITH_TOKEN

# Only this repository path
machine packages.example.invalid/debian
login REPLACE_WITH_USERNAME
password REPLACE_WITH_TOKEN

Use separate path-qualified entries when one server hosts repositories with different credentials. Avoid multiple entries with the same hostname and no paths because older APT versions had less predictable compatibility. A path ending in a slash is significant: machine packages.example.invalid/deb/ does not match a URI beginning /debian.

If the scheme is omitted, the entry matches HTTPS and tor+https, not ordinary HTTP. You can include a protocol explicitly when that is what the URI requires:

machine https://packages.example.invalid/debian
login REPLACE_WITH_USERNAME
password REPLACE_WITH_TOKEN

5. Test APT without exposing the credential

First check the configured source list and ask APT to refresh its metadata. This can contact the repository and update local package lists, so schedule it appropriately. Elevated command:

sudo apt-get update

Checkpoint: the relevant repository should no longer return an authentication error. A successful run may still report unrelated warnings from other configured sources. Do not paste output containing URLs with embedded credentials, and remember that the auth file itself remains sensitive.

If the request fails, check these in order:

6. Remove or rotate credentials safely

When a token is replaced, edit the same block and run sudo apt-get update again. If access is no longer needed, remove only the matching block with sudoedit. Do not delete the whole fragment if it contains other services.

Warning: deleting the file is an access change, and revoking a token at the repository is irreversible from this machine. Have the replacement credential ready before revoking the old one, then remove the old value and test. To undo this guide's configuration while keeping the file for later reuse, clear the block and save it with mode 600.

Done means