skip to content

When you regenerate verification metadata with the `pgp` mode, how do you keep PGP key lookups fast and offline-friendly, and what is the keyring export file for?

level: seniorimportance: should knowfreq 35%

answer

  1. --export-keys
  2. verification-keyring.keys (armored) / .gpg (binary)
  3. local keyring = perf/offline cache
  4. <key-servers enabled=false> for deterministic CI
  5. trust still in metadata.xml, not the keyring

basics

~10 s

Add --export-keys when writing metadata so trusted public keys are exported to a local keyring (gradle/verification-keyring.keys). Builds then read keys locally instead of hitting keyservers, making PGP verification faster and offline-capable.

solid answer

~40 s

When you generate metadata with `pgp` mode, Gradle must fetch each artifact's signing public key from keyservers to validate signatures — slow and a network dependency. To avoid that on every build, you run `--write-verification-metadata pgp,sha256 --export-keys`, which exports all the trusted public keys into a local keyring committed to VCS: `gradle/verification-keyring.keys` (ASCII-armored, human-readable) and/or `gradle/verification-keyring.gpg` (binary). On subsequent builds Gradle resolves keys from this local keyring first and only falls back to configured keyservers for unknown keys. You can disable keyservers entirely (`<key-servers enabled="false"/>` in the XML) so the build is fully offline and deterministic. The keyring is a convenience/perf cache of trust — the actual trust decisions still live as `<trusted-key>`/`<pgp>` entries in verification-metadata.xml.

code

bash · 7 lines
bash
# Export trusted public keys to a local keyring while regenerating metadata
./gradlew help --write-verification-metadata pgp,sha256 --export-keys

# Files produced under gradle/:
#   verification-keyring.keys  (ASCII-armored, review in PR)
#   verification-keyring.gpg   (binary, faster to load)
# Commit them so CI verifies PGP offline.

go deeper

for a junior

Aware that PGP verification needs public keys and that a keyring file can be exported, but not expected to manage it.

for a middle

Know --export-keys produces gradle/verification-keyring.* and speeds up/offlines builds versus keyserver lookups.

for a senior

Explain keyring-as-cache vs trust-in-metadata, disabling keyservers for deterministic CI, and the pgp,sha256 fallback rationale.

for a principal

Define org policy on signed-only artifacts, who reviews key/trust changes, keyring rotation, and the security/perf tradeoff of offline-enforced builds.

## The problem PGP mode introduces In `pgp` mode, Gradle validates each artifact's `.asc` detached signature against the **public key** of the signer. To do that it needs the public key. By default it fetches keys from configured key servers (e.g. `keyserver.ubuntu.com`). That means: - Every fresh build/CI run may hit the network to download keys. - Keyservers are flaky and sometimes slow or down. - Builds aren't deterministic/offline. ## The local keyring as a trust cache Gradle lets you **export** all the public keys you trust into a local keyring stored in the repo, so it never needs the network for known keys. Generate it by adding `--export-keys`: ```bash ./gradlew build --write-verification-metadata pgp,sha256 --export-keys ``` This produces (under `gradle/`): - `verification-keyring.keys` — ASCII-armored, diff-friendly, reviewable in PRs. - `verification-keyring.gpg` — binary, faster to load. Gradle prefers the binary keyring for speed but you can keep the armored one for review; many teams commit both. On later builds Gradle reads keys from the local keyring first and only contacts key servers for keys it doesn't have. ## Going fully offline / deterministic For reproducible CI you can turn keyservers off in `verification-metadata.xml`: ```xml <configuration> <verify-metadata>true</verify-metadata> <key-servers enabled="false"/> </configuration> ``` Now any key not in the keyring is a hard failure rather than a silent network fetch — stronger guarantees and no network dependency. You must re-run `--export-keys` whenever you trust a new signer. ## Keyring vs. trust entries — don't confuse them The keyring only **holds key material**; it is not the trust decision. Trust still lives in `verification-metadata.xml` as `<trusted-key id="..."/>` or per-artifact `<pgp value="..."/>` entries. So review BOTH files in a PR: the metadata says "I trust this key for this artifact", the keyring supplies the bytes of that key. ## Practical loop 1. Add/upgrade a dependency. 2. `./gradlew help --write-verification-metadata pgp,sha256 --export-keys` (broad task set). 3. Review the diff in metadata + keyring (a trust change!). 4. Commit. CI now verifies offline.

  • Does the keyring file decide which keys are trusted?
    No. The keyring only stores public-key bytes so Gradle can validate signatures offline. The trust decision lives in verification-metadata.xml as <trusted-key>/<pgp> entries. Review both when changes occur.
  • How do you make PGP verification fully deterministic in CI?
    Commit the exported keyring and disable key servers via <key-servers enabled="false"/> in the XML. Then any key not already in the keyring fails the build instead of triggering a network fetch.
  • Why prefer sha256 alongside pgp (pgp,sha256) rather than pgp alone?
    Not every artifact is signed. With pgp,sha256 Gradle verifies signatures where available and falls back to a recorded checksum otherwise, so unsigned artifacts are still pinned rather than left unverified.

saying these in an interview costs you the question

  • Thinking the keyring file is where trust is declared (it's just key material).
  • Assuming PGP mode is offline by default — it hits keyservers unless you export keys/disable servers.
  • Committing keyring but leaving keyservers enabled and calling it 'deterministic'.

context