Cache access becomes an explicit permission
GitHub made a new cache-mode control generally available on September 10, 2026, for GitHub Actions on all plans. The setting lets a workflow or an individual job receive one of four relationships to the Actions cache: read, write, write-only or none. Job-level settings override a workflow-level setting. GitHub says the cache service enforces the selected mode through scoped cache tokens, so the restriction is more than a convention that each workflow author must remember to follow.
Dependency caches speed continuous integration by preserving files that would otherwise be downloaded or rebuilt during every run. A job can restore a matching cache before installing dependencies or compiling code, then save a new entry after a successful run when no exact match exists. This shared state reduces repeated work across projects and teams, but it also crosses time and trust boundaries. Files written by one run can be restored by another run with different permissions and a different purpose.
The new control separates operations that were often bundled together. Read permits restoration but prevents saving. Write allows both. Write-only permits saving without consuming an earlier cache, which can suit a trusted producer that rebuilds state from known inputs. None blocks both directions. When an operation is disallowed, supported cache tooling skips it, records what happened and lets the job continue. A skipped restore behaves as a cache miss, while a skipped save simply leaves no new entry.
Secure defaults still allow deliberate exceptions
GitHub classifies some workflow triggers as trusted for cache purposes and others as low trust. When cache-mode is omitted, trusted triggers such as push receive write access, while low-trust events that operate in the default branch context receive read access. GitHub lists pull_request_target, issue_comment and workflow_run among the latter group. These runs may consume an existing default-branch cache but cannot create or overwrite one under the default policy.
That default addresses a specific supply-chain risk. A low-trust run may process a contribution or other input controlled by someone without repository write access. If the run can place altered files into a shared cache, a later privileged workflow might restore and execute them. Restricting the first run to reading breaks the write side of that path while preserving much of the speed benefit from caches maintained by trusted runs.
The restriction is not a hard ban. A workflow author can explicitly assign write or write-only to a low-trust event, overriding the read default. GitHub adds a warning annotation when such an override grants write access, but the workflow can proceed. That design preserves flexibility for unusual build systems, yet it puts the security decision back on the repository owner. A warning communicates risk; it does not prevent a hazardous configuration or prove that cached output is safe.
GitHub recommends narrower patterns before making that exception. A trusted workflow triggered by a push can maintain the cache, while low-trust jobs declare read and reuse it. If a team still enables writing from a low-trust context, the important question is not merely who started the workflow. It is whether untrusted code, files or parameters can influence the cached paths before they are saved, and what a later workflow will do with those files.
Reusable workflows need a caller-side ceiling
The most subtle behavior appears when one workflow calls another. An explicit cache-mode on the calling job, or one inherited from the caller workflow, caps what the reusable workflow may request. A called workflow cannot expand read into write, for example. If it asks for access beyond the explicit ceiling, GitHub validates the combination and refuses to start the run. This gives platform teams a way to publish reusable automation without surrendering the caller's cache policy.
The ceiling must actually be declared. GitHub's dependency-caching reference documents an important exception to the simple inheritance story: when the caller neither sets nor inherits an explicit cache-mode, a reusable workflow can explicitly request write even if the caller's low-trust trigger would otherwise default to read. Teams that want a firm read-only limit must therefore put cache-mode: read on the calling job rather than rely only on the trigger-derived default.
This distinction separates a default from a delegation boundary. Defaults help existing workflows behave more safely without edits. Explicit caller limits express an instruction that downstream reusable code cannot exceed. For organizations with centrally maintained workflow libraries, the latter is easier to audit because the permission is visible at the call site. It also reduces the chance that a later revision of a reusable workflow quietly acquires broader cache access than its caller intended.
Read and write-only are not points on a single ladder. They grant different capabilities, so GitHub treats a mismatch as an excessive request rather than choosing whichever sounds narrower. A caller limited to write-only cannot invoke a reusable workflow that requests read. This is useful precision: preventing a job from consuming inherited state can matter just as much as preventing it from publishing state.
