GitHub Actions cache-mode blocks cache writes from untrusted pull requests
GitHub Actions added a cache-mode setting that limits each workflow or job to read, write, write-only, or none, and blocks cache writes on pull_request_target by default so an untrusted pull request cannot poison the cache the next trusted run reads.

Image: GitHub
Why it mattersCache poisoning from a fork was one of the last ways a pull request could put attacker-controlled bytes on the runner that later merged the fork, and cache-mode removes it without asking every repository to patch its workflows.
GitHub Actions has made cache-mode generally available on all plans. The setting is made at the workflow or job level and grants the run one of four levels of access to the Actions cache: read, write, write-only, or none. GitHub says the change is meant to prevent unnecessary restores or saves and to protect trusted workflows from cache poisoning.
What each mode does, and what the new defaults are
read allows a run to restore from the cache but not save to it. write allows both restores and saves. write-only allows saves and blocks restores. none prevents all cache access.
The defaults now depend on the trust level of the event. GitHub Actions defaults read for low-trust events, and names pull_request_target as the example. It defaults write for trusted events such as push. Workflows that never set cache-mode continue to use the existing secure defaults, so the behaviour change is opt-in for anyone who wants tighter control and automatic for the case the setting was designed for.
Reusable workflows cannot get more than their caller granted
Job-level settings override workflow-level settings, and the mode is enforced by the cache service rather than by the workflow file. That matters for reusable workflows: GitHub says a called workflow cannot receive more cache access than the caller gave it, so a repository that grants a reused workflow read cannot be surprised by that workflow writing to the cache without permission.
Explicitly declaring a cache-mode also overrides the read-only default for low-trust events. GitHub warns that declaring write or write-only on pull_request_target can increase the risk of cache poisoning, and adds a warning annotation on the workflow when the declared mode grants write access on those events.
The attack this blocks
Cache poisoning through Actions was a known way to move attacker-controlled bytes onto trusted runners. A pull request from a fork runs in a workflow that saves something to the cache. A later job on a trusted branch restores that same key, and now the trusted job has whatever the fork put there: a rebuilt dependency, a rewritten binary, a poisoned lockfile. The attack worked because the cache was a single shared store keyed on hashes that a pull request could influence.
The default of read on pull_request_target blocks the write step of that attack in the cache service itself, so the workflow file does not need to change. Existing repositories do not need to change anything to get the new default, and a workflow that genuinely needs write access from an untrusted event has to declare it explicitly and accept the warning annotation.
write-only is the other useful setting. A trusted job that builds shared artefacts can be allowed to save without letting it read whatever a fork happened to write earlier, so a compromised build step cannot use the cache as a general side channel.
Cache mode is generally available on GitHub.com for all GitHub plans, and the configuration is described in the cache-mode workflow syntax documentation.
Source
GitHub Changelog: Control GitHub Actions cache access with cache-mode
This item was written by an AI system from the linked source. Reveneau is responsible for what it publishes.
Get AI News in your inbox
New developer tools, model and agent releases, and how teams are actually using them to release software. Short, and only when there is something worth reading.


