Help Us Improve GitHub Actions Cache Isolation 🔧 #194493
Replies: 7 comments 5 replies
-
|
This is a great start! Some feedback:
If a workflow has a setting like the one in the example then a nightly build that uses cache write (common and probably desired) could end up poisoning a workflow such as the below. runs-on: ubuntu-latest
# ...but allow the release build to populate the cache.
cache-mode: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}To encourage true SLSA L3 compliance the guidance for publication should be to not use caching or use it in write mode. Even better? The NPM CLI should create a warning when it is publishing to NPM in a workflow with cache consumption & the workflow had a cache hit prior.
|
Beta Was this translation helpful? Give feedback.
-
|
This looks like the right direction. One framing that may help: cache access is not only a performance feature. It is an execution authority surface. If a workflow can write to a shared cache, it can influence future executions that may run in a more trusted context. That means cache-mode is effectively part of the authority granted to the workflow before execution starts. So my main suggestion is: make the effective cache authority visible before execution and record it after execution. That would make cache-mode not just a workflow option, but a pre-execution admission signal for whether this run should be allowed to interact with shared cache at all. |
Beta Was this translation helpful? Give feedback.
-
|
This is off-topic, but please note that your examples are pinned to The actions team could do the world a service by fixing the starter-workflows repository to be remotely current. Then fewer people would pay money to run dependabot to update to remotely current versions of things like |
Beta Was this translation helpful? Give feedback.
-
|
The idea of a cache: readable | writable | noneNot using Personally, I've removed all use of cache from my action a long time ago because it's too dangerous and the speedup it gets wasn't worth the risk it introduced. (For bigger systems, the problem is more interesting.) In general, I don't think I like the cache model at all. Unless I can access the contents of the cache to inspect it later, it's useless to me. And the core problem w/ the cache is that people can flush it and race it and things. My approach has been to use persistent stores instead because those give me the properties I care about. -- I can achieve more of that today by using immutable releases and just making a releases out of any artifact I want to reuse.
|
Beta Was this translation helpful? Give feedback.
-
|
This is a really valuable improvement direction, especially for supply-chain security and reproducible CI/CD pipelines. One additional improvement that could help significantly is adding cache provenance visibility. Right now, workflows can restore caches without clearly showing: Having that metadata exposed directly in workflow logs or the Actions UI would make debugging and trust decisions much easier. I also strongly agree with the concern around cache poisoning risks in release or publishing workflows. In many projects, caches are restored before publishing artifacts or packages, which can become risky if upstream dependencies or cache writers are compromised. GitHub’s current cache documentation already mentions branch-scoped behavior, but more granular trust controls would be extremely useful: Some ideas that could improve this further: Another useful enhancement could be exposing cache provenance through the API, similar to artifact metadata, which would help larger organizations audit CI behavior more effectively. From a SLSA and software supply-chain perspective, this direction makes a lot of sense: Overall, this looks like a strong step toward safer and more predictable GitHub Actions caching behavior. |
Beta Was this translation helpful? Give feedback.
-
|
This is a really valuable improvement direction, especially from a supply-chain security and CI integrity perspective. One thing that could improve this proposal even further is adding cache provenance visibility directly inside the Actions UI and API. Right now, when a workflow restores a cache, there is very little visibility into: Exposing that metadata would make debugging and trust decisions significantly easier for maintainers and security teams. I also strongly agree with the concern around cache poisoning risks in publishing and release workflows. Many projects restore dependency caches before publishing artifacts or packages, and that can become dangerous if less-trusted workflows are able to influence shared cache state. The proposed direction of separating cache authority from general workflow permissions makes a lot of sense. In practice, cache access behaves more like an execution trust boundary than just a performance optimization feature. Some additional ideas that could strengthen this further: It may also be useful to expose cache provenance information through the API, similar to artifacts metadata, so larger organizations can audit CI behavior programmatically. Relevant references: Overall, this feels like a strong step toward safer and more predictable GitHub Actions caching behavior without breaking existing workflows. |
Beta Was this translation helpful? Give feedback.
-
|
A couple quick points
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Actions Cache
TLDR;
cache-modesetting for GitHub Actions Cache at the workflow and job level.write,read, andnone.Hi everyone 👋
We are exploring a change to GitHub Actions Cache and we want your opinion before we finalize the design. This post focuses on the first phase of work. Please share thoughts, concerns, and alternatives in the comments.
The problem
If you use GitHub Actions Cache today, every workflow that runs on your repository can write to the same shared cache namespace for a branch. That includes workflows triggered by pull requests, issue comments, scheduled jobs, and AI or agent driven workflows that may execute untrusted input.
The cache credential (
ACTIONS_RUNTIME_TOKEN) is handed to every workflow run automatically. It is issued independently of:permissions:block on your workflow or job,That means a workflow you consider untrusted can still place content into the cache (within the scoping rules linked above). A later workflow you consider trusted, such as your release pipeline, may then restore that content as part of its build. The workflow ends up consuming inputs it never produced and never reviewed.
The customer impact:
Independent security research by Adnan Khan has documented how these scoping rules can still be bypassed in practice — see CI/CD Pipeline Cache Poisoning and Compromising Angular via the Dev Infrastructure for concrete examples. This proposal gives workflow authors an explicit, declarative control on top of those existing scoping rules.
We want to close that gap, and we want to do it in a way that does not break the workflows you have today.
What we are proposing
A new key called
cache-modethat you can set at the workflow level, the job level, or both. It accepts three values:writereadnoneKey properties of the proposal:
write. Nothing changes for existing workflows unless you opt in.cache-modeisreadornone, the runtime token issued for the job carries restricted cache claims. The cache service validates them. No action, script, or step can bypass the declared mode.job['cache-mode'](use bracket syntax because the key contains a hyphen)ACTIONS_CACHE_MODEwith valueread,write, ornoneSetup actions such as
actions/setup-nodeoractions/setup-pythoncan readACTIONS_CACHE_MODEduring their post job step and skip the tar and compression work entirely when writes are not allowed, so you do not pay for I/O you cannot use and you do not see confusing authorization errors in your logs.Example workflows
Scenario 1. Workflow level default of
readfor a pull request checkFile:
.github/workflows/pr-check.ymlScenario 2. A single job overrides the workflow default to
noneFile:
.github/workflows/pr-check-isolated.ymlScenario 3. Trusted release job explicitly opts into
writeFile:
.github/workflows/release.ymlScenario 4. Runtime detection for conditional cache saves
File:
.github/workflows/conditional-save.ymlScenario 5. Agentic Workflows that should never write cache
GitHub recommends running AI agents inside Agentic Workflows rather than wiring "naked" agents directly into ordinary workflows triggered by
issue_commentor similar events. Agentic Workflows already provide isolation and policy controls for untrusted natural language input.cache-mode: noneis a complementary defense in depth: even an Agentic Workflow that would not normally need cache access can declare it explicitly, so the cache surface is removed entirely from the agent's environment.File:
.github/workflows/agentic.ymlQuestions we want your opinion on
cache-modethe clearest name, or is there a name that would communicate the intent better? What alternatives have you considered?read,write, andnonethe right set, or do you need finer granularity such as per key or per scope rules?ACTIONS_CACHE_MODEin your post job step workable for you? What is missing, awkward, or duplicative with what you already do?cache-modesurfaced outside the workflow file, for example in run summaries, the API, or audit logs? What problem would that solve for your team, and where would extra surface area get in the way?Note
Phase 1 only ships the workflow level
cache-modekey, which means any author can opt in today without admin involvement. We know that to makereada secure default across an org or enterprise, admins also need a policy control. Something like a per org default value plus an allow list of repos or workflows that may declarewrite. We are intentionally scoping that out of Phase 1 so we can get the workflow contract right first, but we want your input on what that policy surface should look like. See question 6 below.If something here does not match how your team uses Actions Cache, we want to hear it. The goal of Phase 1 is to give you a switch you can use today without forcing changes on anyone who is happy with the current behavior.
Thanks for reading 🙏
Beta Was this translation helpful? Give feedback.
All reactions