Trusted Artifact Isolation


Trusted artifact isolation splits every cache key into a trusted and an untrusted entry, and lets you decide per workload which of the two a build may write and read.

It applies to the caches an Edge node serves: Artifact Cache, Setup Cache, and the Build Cache entries an Edge node stores.

A build set to Require trusted cannot be served content written by a workload you have not granted trusted write access. This closes the cache-poisoning path where a pull request from a fork writes a cache entry that a later release build consumes.

Trusted artifact isolation is off by default, and upgrading does not turn it on. Until you enable it, every build reads and writes exactly as it does today: writes are untrusted, and reads resolve a trusted entry when one exists.

How Isolation Works

Every cache key addresses two entries: a trusted one and an untrusted one. Which entry a build writes, and which it may read, depends on the isolation levels set on the workload identity rule that its credentials match.

Isolation applies to OIDC workload identity credentials only. Levels come from claim matching, so there is no way to assign one to an access key.

Isolation Levels

Each workload identity rule carries two levels, set under Universal Cache isolation on the rule as Read isolation level and Write isolation level.

Write levels
Level Effect

Untrusted

The build writes the untrusted entry for a key. This is the default.

Trusted

The build writes the trusted entry for a key.

Read levels
Level Effect

Prefer trusted

The build resolves the trusted entry when one exists, and the untrusted entry otherwise.

Require trusted

The build resolves trusted entries only. A key with no trusted entry is a miss.

Three of the four pairs are valid. Write Trusted with read Prefer trusted is refused. A producer configured this way accepts untrusted content as input but publishes it as trusted, so it can carry untrusted content into the trusted pool. That is the path isolation exists to close, so Develocity refuses the pair rather than letting you configure it.

Before You Enable Isolation

Upgrade Develocity before any Edge node. An older Controller reports no isolation levels, and an Edge node takes that literally, so builds miss every key until the upgrade completes.

Every Edge node must run version 2.3.0 or later before you set Require trusted on any workload identity rule. An older node has no isolation behavior at all: it accepts entries peered from a newer one, and it serves an untrusted entry to a Require trusted build instead of refusing it.

That refusal is the guarantee isolation exists to provide, so an Edge node left behind keeps the cache-poisoning path open for every build routed through it. The build is not told. The response carries no X-Trust-Class-Applied header and no error, the Artifact Cache CLI prints no classification summary, and no configuration page reports the mismatch. A cache hit from an older node is indistinguishable from a legitimate trusted hit. See Confirming the Applied Classification.

Check the version of every Edge node before you enable isolation, and again after adding a node. The Version column on the Administration  Edges page reports the version of every connected node, including the co-located node that Develocity manages.

Choosing Levels for Each Workload

A few workload shapes cover most deployments.

Workload Write Read Why

Release and trunk builds whose output others consume

Trusted

Require trusted

Their inputs come only from trusted entries, and their outputs become the trusted pool.

Pull request and fork builds

Untrusted

Prefer trusted

Contributor code cannot write the trusted pool, and reads keep their hit rate.

Nightly and integration builds that gate a release

Untrusted

Require trusted

They verify against trusted inputs without publishing trust of their own.

Builds presenting no workload identity token

Not applicable

Not applicable

The default behavior applies, so there is nothing to set.

Trusted is one shared class, not a per-branch boundary. Every entry a trusted producer writes joins the same pool, so a Require trusted reader trusts every identity you have granted trusted write access. Granting that access narrowly is what makes the release recommendation hold.

Enabling Isolation

Turning isolation on is the disruptive step. A workload identity rule with no levels set resolves to write Untrusted and read Require trusted. At that moment every entry in the cache is untrusted, so every read misses until trusted producers repopulate the trusted side.

The Read isolation level and Write isolation level controls are hidden while isolation is off. You can choose either order:

  • Enable isolation, then set levels on each workload identity rule immediately afterwards.

  • Write the levels through unattended configuration first, then enable isolation.

Levels set after enabling take effect from that point. Nothing is lost by setting them late. The trusted side takes longer to fill.

Save stores an isolation change as a draft without applying it. A banner then appears at the top of the page: There are saved configuration changes that have not been applied. Select Apply in that banner to put the change into effect. If you leave the page or select Discard first, you lose the change.

This applies to the Enable Universal Cache isolation checkbox and to the Read isolation level and Write isolation level on each workload identity rule.

Enable Isolation in the User Interface

  1. Navigate to Administration  Access control  Workload identity.

  2. Under Universal Cache isolation, select Enable Universal Cache isolation.

  3. Select Save, then select Enable in the confirmation dialog.

  4. Select Apply in the banner at the top of the page, then confirm.

Develocity does not restart when you apply an isolation change.

Set Levels on a Workload Identity Rule

  1. Navigate to Administration  Access control  Workload identity and select the rule.

  2. Under Universal Cache isolation, set Read isolation level and Write isolation level.

  3. Select Save.

  4. Select Apply in the banner at the top of the page, then confirm.

Develocity collects saved changes into a single draft. You can set levels on several rules and apply them together, though none take effect until you do.

What Trusted Does Not Isolate

Image names do not create a trust boundary. A different image name resolves a different manifest, but the entries that manifest references sit in the same pool. Entry keys are chosen by the client. Two trusted branches can therefore write the same entry whatever image names they use. For what an image name does control, see Images.

No cache path isolates by branch. If you need a branch boundary, isolation is not the mechanism that provides one.

Builds That Present No Workload Identity

Access key builds, anonymous builds, and any credential that matches no workload identity rule all behave the same way: they write untrusted entries and read a trusted entry when one exists.

This behavior is not configurable, and it does not change when isolation is off or on. Two consequences follow:

  • Such a build can never write a trusted entry, whatever roles its credential carries. It cannot poison a Require trusted reader.

  • You cannot restrict such a build to trusted content only. If you need that guarantee for a workload, move it to OIDC workload identity.

Anonymous cache access resolves a trusted entry wherever one exists, and that cannot be turned off. Take it into account when deciding whether to grant anonymous cache access at all.

Confirming the Applied Classification

Develocity reports the classification it applied on each cache response, in the X-Trust-Class-Applied header. It carries TRUSTED or UNTRUSTED.

An absent header means Develocity applied no classification, which is not the same as UNTRUSTED. A node that predates isolation reports nothing.

The Develocity Artifact Cache CLI reads this header and logs the classification for each operation, then reports an end-of-run summary per cache:

Artifact cache: restored 2 trusted entries out of 5
Setup cache: restored 1 trusted entry out of 1

After setting a producer’s write level to Trusted, confirm from that job’s summary that trusted writes are happening. A summary showing zero trusted entries means no credential on that job is classified as trusted. Adjust the workload identity rule’s claim matchers so the job matches it.

Conflicting Levels

A request can match more than one workload identity rule. When the matched rules disagree on a level, or combine into the refused pair, Develocity refuses the cache operation with 409 Conflict rather than resolving it at the weaker level.

The response carries X-Cache-Isolation-Conflict naming the cause, because the remedies differ:

Cause Remedy

CACHE_ISOLATION_MATCHER_CONFLICT

Two matched rules name different levels. Reconcile them, or narrow the claim matchers so a build matches one.

CACHE_ISOLATION_UNSAFE_COMBINATION

Two rules that are each valid combine into write Trusted with read Prefer trusted. Remove one of the two levels.

CACHE_ISOLATION_UNRECOGNIZED_LEVEL, CACHE_ISOLATION_UNRECOGNIZED

The node cannot read a level the Controller sent. Upgrade the node.

The header is diagnostic. No build tool reads it, so a conflicted operation surfaces in the build the way any unexpected cache error does. Read the header, or the Edge node log, to find which of the four causes applies.

Disabling Isolation

Turning isolation off returns every workload identity to the default behavior: untrusted writes, and reads that resolve a trusted entry when one exists. Develocity preserves the levels on each rule, but they stop taking effect.

Clear Enable Universal Cache isolation under Administration  Access control  Workload identity, select Save, then select Apply in the banner. Isolation stays on until you do.

Nothing is deleted. Trust class values on existing entries stay on disk, and reads keep preferring a trusted entry, so clearing a workload’s levels costs no cache hits.

A token minted while isolation was on keeps its levels until it expires. Disabling isolation takes effect immediately for builds that present an OIDC token directly, and at the next token exchange for builds using a minted Develocity token. Turning isolation off does not immediately stop trusted writes.

Nothing reports the levels a token carries. They are not listed with its permissions, and no page or API shows them, so you cannot tell from a token whether it still holds levels granted before you disabled isolation. The applied classification on each cache response is the only signal, and it reports what a build did after the fact rather than what its token allows. See Confirming the Applied Classification.