How Debsign Uses GPG to Sign Changes and DSC Files

The debsign utility is a dedicated tool provided by the Debian devscripts suite that applies cryptographic signatures to Debian Source Control (.dsc) and upload description (.changes) files using GNU Privacy Guard (GPG). This article explains how debsign resolves target files, selects the appropriate GPG private key, executes the clearsigning process, and ensures package integrity for authorization into the Debian package archives without requiring package rebuilds.

Target Files and the Purpose of Signing

In Debian package maintenance, build artifacts must be authenticated before an upload daemon (such as DAK) accepts them into an archive repository. The two primary targets for signatures are:

  1. The .dsc file: Contains metadata regarding the source package, along with cryptographic hashes (such as SHA-256) of the upstream tarball, Debian patch files, and associated packaging materials.
  2. The .changes file: Acts as the manifest for an upload, detailing the architecture, distribution, changelog entry, and cryptographic hashes of the generated binary packages (.deb) and the .dsc file itself.

Signing these files creates a cryptographically verified chain of custody. Instead of signing large binary .deb archives directly, the maintainer signs the metadata files containing the hashes of those binaries.

How Debsign Locates the GPG Key

When debsign is invoked, it determines which private key to use using a defined hierarchy:

  1. Command-Line Overrides: If the maintainer supplies the -k<key-id> or -m<maintainer-name> options, debsign explicitly invokes GPG using that specific identifier.
  2. Environment Variables and Configuration Files: If no command-line flag is provided, debsign checks configuration options in /etc/devscripts.conf or ~/.devscripts (specifically DEBSIGN_KEYID). It also references variables like DEBEMAIL or DEBFULLNAME.
  3. Parsing the Control Metadata: If no key is explicitly configured, debsign reads the target .changes or .dsc file to extract the Changed-By: or Maintainer: field. It extracts the name and email address to form a GPG user ID query.

The Cryptographic Signing Process

Once the key ID and target files are resolved, debsign coordinates with GPG through the following automated sequence:

  • Signature Stripping: If the target .dsc or .changes file has already been signed (for instance, by an automated build system or an earlier maintainer), debsign parses the file, strips the existing ASCII-armored PGP boundary blocks, and extracts the original unsigned text.
  • DSC File Processing: If signing a .changes file that references a local .dsc file, debsign signs the .dsc file first. It invokes GPG using the --clearsign option, which wraps the file's plain text between -----BEGIN PGP SIGNED MESSAGE----- and -----BEGIN PGP SIGNATURE----- markers.
  • Hash Recalculation: Because signing the .dsc file alters its contents, file size, and cryptographic checksums, debsign recalculates the SHA-1, SHA-256, and MD5 hashes of the newly signed .dsc file and automatically updates the corresponding entries inside the .changes file.
  • Changes File Processing: Finally, debsign signs the updated .changes file using GPG's --clearsign function.

All file modifications are performed using temporary files and atomic moves to ensure that files are not corrupted if the GPG operation is canceled or fails.

Handling GPG Execution and Agents

debsign executes GPG (typically gpg or gpg2) as a child process. It relies on the environment's running gpg-agent to handle passphrase entry, PIN prompts, or hardware security token interactions (such as smart cards or YubiKeys). If the key requires a passphrase that is not cached, the standard pinentry dialog will open to authenticate the maintainer.

Remote Signing Workflow

A distinct architectural feature of debsign is its native support for remote signing over SSH. Maintainers frequently build packages on remote servers or within build chroots where private GPG keys are not stored for security reasons. By executing debsign [user@]remotehost:path/to/package.changes, the utility downloads the necessary .changes and .dsc files locally via scp or sftp, applies the local GPG signature, updates the checksums, and copies the signed versions back to the remote server.