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 sits 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 closes
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 path worked because the cache was a single shared bucket keyed on hashes that a pull request could influence.
The default of read on pull_request_target cuts the write side of that path at the service, not at the workflow file. 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 say so out loud and accept the warning annotation.
write-only is the other useful shape. 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 lives in the cache-mode workflow syntax documentation.
Source
GitHub Changelog: Control GitHub Actions cache access with cache-mode
Source: GitHub Changelog
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 shipping with them. Short, and only when there is something worth reading.



