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.

The control narrows authority, not cache integrity

Cache-mode does not sign, verify or inspect cached files. GitHub explicitly says Actions caches are unsigned and unverified. A workflow with read access can extract their contents, and restored files may later be executed. The new setting can reduce which jobs create or consume that state, but it cannot establish that a permitted writer produced correct files or that a restored dependency matches an external source of truth.

Cache keys are also selectors, not attestations. The cache action first looks for an exact key, then may use partial matches and ordered restore keys. That behavior is useful when nearby dependency states can share work, but broad fallback keys increase the importance of treating restored content as input that needs appropriate validation. Existing branch and tag scoping limits where entries can be found, yet multiple workflows within an eligible repository scope can share caches.

Secrets do not belong in cached paths. GitHub warns that people able to open a pull request may be able to read caches associated with the base branch. Separating read from write does not turn a cache into confidential storage. Credentials should remain in the platform's secret mechanisms, and cache-writing workflows still need careful permissions, pinned dependencies and protection from unsafe evaluation of contributed data.

The practical advance is least privilege for a performance feature that previously exposed a coarser operational choice. Teams can identify trusted cache producers, allow broader sets of jobs to consume their output and deny cache access where reuse offers little value. Write-only adds a useful producer role, while explicit caller caps make reusable workflows easier to contain. The remaining work is architectural: choose cache keys carefully, keep sensitive material out, review every write-capable low-trust override and remember that faster reused state is not necessarily verified state.