Safeguard
Developer Tools•

What does GitHub Actions cache-mode do and which value should you use?

cache-mode sets whether a job can restore, save or neither. Low trust triggers get read only access to default branch caches. Here is what to set and why.

Safeguard Security Team
4 min read

The cache-mode key controls how much cache access a GitHub Actions job gets: read, write, write-only or none. If you omit it, trusted triggers get write access and low trust triggers get read. Use read for jobs that only consume a cache, and keep write for a trusted build on a push to the default branch.

The problem it addresses

A build cache is an input to your build. If an attacker can write a bad entry that a privileged workflow later restores, your build trusts it. GitHub's documentation calls this class of attack cache poisoning.

Some workflows run in response to events that people without write access can start, such as a fork pull request or an issue comment. When these run in the context of the default branch, they could write a malicious cache that a later, more privileged workflow restores.

The default rules

According to GitHub's dependency caching reference, only these triggers can create or overwrite caches in the default branch scope: push, workflow_dispatch, repository_dispatch, delete, registry_package, page_build and schedule. Runs from any other event that resolves to the default branch get read-only access to caches in that scope. That includes triggers whose payload or initiator someone outside the repository can influence, such as pull_request_target, issue_comment and workflow_run.

The pull_request event is not affected, because its caches are already scoped to the merge ref and cannot be written to the default branch scope.

When a read-only run tries to save, the save fails but the step and job do not. You get a warning in the log.

The four values

ValueRestore cachesSave caches
readYesNo
writeYesYes
write-onlyNoYes
noneNoNo

You can set cache-mode at workflow level, job level or both. A job level value overrides the workflow level for that job. The runner exposes the effective mode in the ACTIONS_CACHE_MODE environment variable, and the cache action honours it. When a restore or save is skipped because of the mode, the action logs an informational message and the run continues. A skipped restore counts as a miss.

In reusable workflows, the mode propagates from the caller. An explicit mode on the calling job, or inherited from the caller workflow, limits what the called workflow can request.

What to set

  1. Have one trusted workflow, such as a build on push to the default branch, keep the cache fresh. The docs suggest exactly this so low trust workflows can still benefit.
  2. In low trust workflows, use the restore-only action, actions/cache/restore, which makes intent clear and avoids the warning.
  3. For jobs that never need a cache, for example a job that handles credentials, set none.
  4. Treat an explicit write mode on a low trust trigger as an exception that needs a reviewer. The docs say a repository can opt out of the default restriction by declaring a write capable mode, so make sure that choice is deliberate.
  5. Do not store tokens or credentials in cached paths. The docs warn that anyone with read access can create a pull request and access cache contents.

Related reading: who should write to a Gradle remote build cache and a CI cache key that follows your lockfile.

Quick check

Does cache-mode protect pull_request workflows?

Those caches are already scoped to the merge ref and cannot reach the default branch scope, so the default restriction does not apply to them.

What happens if a read-only job tries to save?

The save fails, the job continues, and a warning appears in the log.

Safeguard's policies and gates can enforce workflow rules on pull requests. The free scan at gold.safeguard.sh/scan covers repository dependencies.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.