A workflow run can restore caches from its own branch and from the default branch. It cannot restore caches from child or sibling branches. Pull request runs can also restore from the base branch. So anything written to the default branch cache is readable by many runs, which is why cache contents matter for security.
The rules from GitHub's documentation
- Workflow runs can restore caches created in either the current branch or the default branch.
- If a run is triggered for a pull request, it can also restore caches created in the base branch, including base branches of forked repositories.
- Runs cannot restore caches created for child branches or sibling branches.
- A cache created for a pull request has a limited scope and can only be restored by re-runs of that pull request.
What those rules imply
| Where a cache is written | Who can restore it |
|---|---|
| Default branch | Runs on the default branch, and runs on any branch or pull request that targets it |
| Feature branch | Runs on that branch |
| Pull request | Re-runs of that pull request |
| One feature branch | Not another feature branch |
The default branch is the widest circle, so its cache is the one to protect. A poisoned entry there could be picked up by later builds on many branches. That is why a release or deployment job should be careful about restoring a cache at all, and why the job that writes the default branch cache should be a trusted one.
Practical consequences
- Keep the writer of the default branch cache trusted. Let it run only on pushes to protected branches, from code that has been reviewed.
- Do not rely on a cache for integrity. A cache is a speed feature. Treat restored files as input that could have been altered, especially for compiled output and tool binaries.
- Never store credentials in a cached path. GitHub's guidance is not to store sensitive information such as access tokens or login credentials in a cache, and not to write secrets, tokens or credentials to a cached path.
- Use keys that include a hash of the lock file, so a changed dependency set produces a new entry rather than reusing an old one.
- In release jobs, consider a clean install from a locked file instead of restoring a build cache. That trades speed for a build you can reason about.
Size and lifetime
Caches are not permanent. GitHub removes entries not accessed in over seven days, and by default the limit is 10 GB per repository. When the limit is reached, it removes caches in order of last access date, from oldest to most recent. Two points follow. A busy repository can lose useful caches early. And an old poisoned entry does not stay forever, but a frequently used one stays alive because each use refreshes it, which is a reason to purge after an incident.
After a compromise
If you suspect a workflow or action was compromised, delete the caches as part of cleanup, and rebuild from a clean state. See purge CI caches after a compromise and can fork pull requests poison your GitHub Actions cache.
Quick check
Can a feature branch restore another feature branch's cache?
No. Per GitHub's documentation, runs cannot restore caches created for sibling or child branches. They can restore from their own branch and the default branch.
Is it safe to cache a credentials file for speed?
No. GitHub advises against storing tokens or login credentials in a cache. Fetch credentials fresh in each job.
Sources
Last reviewed: 19 October 2026.