GitHub Actions cache-mode: Checking Cache Permissions Hidden Behind Green CIs
When a CI run finishes green but dependencies are downloaded again on the next run, it is easy to assume the cache key needs fixing first. Now, you must also verify whether the save step was skipped due to permissions. This is because the mere fact that a workflow succeeded does not prove that a cache was actually created.

GitHub announced the general availability of cache-mode on September 10, 2026. On all plans across github.com, you can configure cache access at the workflow or job level. Moving a step forward from previous articles covering read-only defaults, this article focuses on explicit configuration and verification methods.
Confirmed Features: Four Combinations of Restore and Save
read allows restoration only, while write allows both restoration and saving. write-only allows saving only, and none blocks both. The first checklist item is not mistaking the name write for save-only.
A value declared in a job takes precedence over the workflow-level setting. Conversely, in reusable workflow calls, a job cannot receive greater access permissions than what the caller allowed. Do not judge the actual permissions of an entire run solely by reading the declaration in a single file.
A Green Run Is Not Evidence of a Save
The official documentation explains that unauthorized cache operations output informational logs and allow the run to continue. A blocked restore is treated as a cache miss, and a blocked save is simply not performed. The key observation point is that the workflow itself does not fail.
Therefore, it is useful to separate operational records into run success status and cache outcome. In a single run, check which event triggered the execution, which mode was applied, whether a restoration occurred, and whether a save was skipped. This is an operational approach suggested based on official feature descriptions, not a newly provided automated dashboard feature.
Creating a Small Permissions Table Before Application
Examine the actual workflows in your repository to identify cache-producing jobs and cache-consuming jobs. You do not need to group jobs preparing dependencies on trusted branches, jobs testing external changes, and jobs verifying deployment artifacts under the same permissions.
Write down two sentences for each job: Does this job need to read an existing cache? May the results of this job be preserved for the next run to read? If neither is necessary, you can reconsider the habit of attaching caches in the first place. However, actual configurations must be determined in accordance with your repository's trust boundaries and build architecture.
A Minimal Experiment: A Read-Only Consumer Job
For example, specify cache-mode: read at the top level of a test workflow and verify that there are no job-level overrides. Compare whether test results with a cache match test results without one. Since caches should serve as an auxiliary aid to shorten execution time, if accuracy changes in the absence of a cache, you must first inspect your build assumptions.
The passing criterion for this experiment is not a single line of CI success. You must be able to account for restore attempts and skipped saves, and verify them again with the same inputs on the next run. Documenting pre- and post-experiment commits, triggers, effective settings, and log locations will make it easy for colleagues to reproduce your conclusions.
For Reusable Workflows, Read the Entire Call Path
Even if safe defaults are set in shared workflows, the caller and individual job configurations must be reviewed together. The fact that repositories call the same file does not mean they execute with the same permissions.
During code review, trace from the caller to the job's cache declaration and then to the called workflow in order. If the expected permissions differ from the actual logs, find the origin of the configuration before making keys more complex. This is a proposal to reduce troubleshooting time in organizations with heavy reuse, and does not represent measured performance improvement metrics.
Exceptions to Watch and Implementation Order
Explicitly specifying write or write-only on lower-trust events such as pull_request_target can override read-only default restrictions and increases the risk of cache poisoning. In this case, GitHub adds a warning annotation. You should avoid responding by expanding write permissions simply to suppress warnings.
Conversely, choosing to block all caches also carries a cost. Since download and build times may increase, directly compare execution times on a representative job before broadening the scope. Rather than promising performance benefits based on estimated figures, it is better for the team to collaboratively decide on necessary security restrictions and acceptable delays.
Questions Teams Should Verify Right Now
What needs to be done today is not adding the new configuration across all repositories en masse. It is finding cache producers and consumers in a single critical workflow, documenting their permissions, and verifying the evidence of restore and save operations in a single run. For deployment jobs, keep changes small so that the responsible engineer can read the logs and review whether they match expectations.
A practical question that often arises is why the CI succeeded when the save step was skipped. This article explains such confusion based on official behavior, and does not make claims based on separate community surveys or universal failure rates. By independently verifying performance outcomes and permission outcomes when adopting new features, you can more accurately categorize your next cache issue.