After bootstrapping verification, how do you express trust at different granularities — e.g. trusting a specific key only for one artifact versus globally — when maintaining verification-metadata.xml?
answer
- <trusted-key> global (scope by group/name/version)
- <pgp value> per-artifact narrow trust
- pgp,sha256 = signature else checksum
- <trusted-artifacts> exempt javadoc/sources
- narrow = smaller blast radius, more noise
basics
~20 sUse <trusted-key> in the <configuration> block for global trust of a key (optionally scoped by group/module), and per-artifact <pgp value="keyid"/> entries under a component for narrow trust. Narrower scoping limits blast radius if a key is misused.
solid answer
~40 sWhen maintaining the trust file you choose between broad and narrow trust. A global `<trusted-key id="ABC..."/>` under `<configuration><trusted-keys>` trusts that key for everything (you can scope it with `group`, `name`, `version` attributes to limit it to e.g. one publisher's coordinates). Per-artifact trust lives under each `<component>` as `<artifact><pgp value="ABC..."/></artifact>`, meaning "this exact artifact is trusted if signed by this key". `--write-verification-metadata pgp` generates the per-artifact form by default; you promote a key to a scoped `<trusted-key>` manually when one signer publishes many artifacts and you want fewer, auditable entries. There's also `<trusted-artifacts>` to mark certain files (sources/javadoc) as not requiring verification. The tradeoff: global trust is less noisy but wider blast radius; scoped/per-artifact trust is verbose but limits damage if a key is compromised. Always review these as deliberate security decisions.
code
xml · 17 lines<verification-metadata>
<configuration>
<verify-metadata>true</verify-metadata>
<trusted-keys>
<!-- global, scoped to one publisher's coordinates -->
<trusted-key id="D8FE7D8A...A1" group="com.acme"/>
</trusted-keys>
</configuration>
<components>
<component group="org.other" name="lib" version="3.4.0">
<artifact name="lib-3.4.0.jar">
<!-- narrow, per-artifact trust -->
<pgp value="3F22AA...09"/>
</artifact>
</component>
</components>
</verification-metadata>go deeper
Know trust lives in verification-metadata.xml and a key id is recorded per dependency; not expected to design scoping.
Distinguish per-artifact <pgp> from global <trusted-key> and that pgp,sha256 falls back to checksums.
Reason about scoping trusted-key by group/module, the blast-radius tradeoff, and when to promote/collapse entries.
Define org policy for trust granularity, who approves new key ids, and review processes that treat trust additions as security changes.
## Trust granularity is the core maintenance decision Once metadata exists, the ongoing work is deciding *how broadly* to trust. Gradle offers several levels, from artifact-narrow to global: ### 1. Per-artifact PGP (narrowest) Generated by default in `pgp` mode under each component: ```xml <component group="com.acme" name="lib" version="1.2.0"> <artifact name="lib-1.2.0.jar"> <pgp value="D8FE...A1"/> </artifact> </component> ``` Meaning: this exact jar is accepted only if its `.asc` signature validates against key `D8FE...A1`. Very precise; very verbose for big dependency graphs. ### 2. Per-artifact checksum (fallback) When no signature exists, Gradle records a `<sha256 value="..."/>` instead. With `pgp,sha256` you get signatures where possible and checksums otherwise. ### 3. Globally trusted keys (scoped) Under `<configuration>`: ```xml <trusted-keys> <trusted-key id="D8FE...A1" group="com.acme"/> <trusted-key id="3F22...09"/> </trusted-keys> ``` A bare `<trusted-key id>` trusts that key for **any** artifact. Adding `group`/`name`/`version`/`regex` attributes scopes it — e.g. "trust this key only for `com.acme:*`". This collapses many per-artifact entries into one auditable line when a publisher signs everything with one key. ### 4. Trusted artifacts / ignored files ```xml <trusted-artifacts> <trust file=".*-javadoc[.]jar" regex="true"/> </trusted-artifacts> ``` Exempts certain files (e.g. javadoc/sources) from verification entirely — use sparingly. ## The tradeoff - **Global trust**: minimal file, easy upgrades (new versions from the same signer just work), but a compromised key affects everything it covers. - **Per-artifact trust**: maximal precision and smallest blast radius, but every version bump regenerates entries and the file is large/noisy. A pragmatic pattern: keep `--write-verification-metadata` output (per-artifact) as the default, then **promote** well-known publishers to scoped `<trusted-key>` entries to cut noise — documenting why each is trusted. ## Maintenance loop 1. Bump a dependency → regenerate metadata. 2. Inspect new entries: is this a new signer? Should it be a scoped trusted-key instead of dozens of per-artifact lines? 3. Treat every added key id as a code-review-worthy trust decision, not a rubber stamp.
- When would you promote per-artifact <pgp> entries to a scoped <trusted-key>?When a single publisher signs many artifacts/versions with one key. A scoped <trusted-key id=... group=...> collapses dozens of noisy per-artifact lines into one auditable entry and makes version bumps from that publisher pass without regenerating each entry.
- What is the security tradeoff of broad vs narrow trust?Broad/global trust keeps the file small and upgrades smooth but widens the blast radius if a key is compromised. Narrow per-artifact trust limits damage to specific artifacts but is verbose and churns on every version change.
- What does <trusted-artifacts> do?It exempts matching files (commonly javadoc/sources jars) from verification entirely. Useful to reduce noise on non-executable artifacts, but should be used sparingly since exempted files are not checked.
saying these in an interview costs you the question
- Trusting a bare global key for everything without scoping when only one publisher needs it.
- Treating regenerated trust entries as a rubber-stamp rather than a security review.
- Exempting executable jars via <trusted-artifacts> just to silence failures.