By default, no. GitLab appends a suffix to cache keys so pipelines on protected refs use one cache and pipelines on unprotected refs use another. This stops a less trusted branch from writing files a release pipeline later restores. You can turn separation off, but GitLab says to do so only where all Developers are highly trusted.
Why a shared cache is a risk
A CI cache holds files that a later job restores and often runs: downloaded packages, build tools, compiled output. If any developer branch can write to the cache that the release job reads, a bad file placed in an ordinary branch can reach the release build. That is the cache poisoning pattern described in our cache poisoning explainer.
How GitLab separates them
GitLab's caching page says protected and unprotected branches do not share a cache by default. The cache key gets -protected when the pipeline runs on a protected ref for a user with Maintainer or Owner level access, and -non_protected otherwise. For tag pipelines, the protection status of the tag decides the suffix, not the branch it came from.
| Pipeline | Key suffix | Reads protected cache |
|---|---|---|
| Protected branch, maintainer-level user | -protected | Yes |
| Feature branch | -non_protected | No |
| Protected tag | -protected | Yes |
| Unprotected tag | -non_protected | No |
Fallback keys follow the same suffix rule, so a fallback cannot cross the line either.
Cache versus artifacts
The two are easy to confuse. A cache stores dependencies on the runner, or in object storage with distributed caching, and is not shared between projects. Artifacts pass build results between stages and live in GitLab. Neither can reference files outside the project directory. GitLab also states that caching is an optimisation and is not guaranteed, so a pipeline must never depend on a cache hit for correctness.
Steps to keep it safe
- Leave "Use separate caches for protected branches" on. Find it in the project's CI/CD settings.
- Use
cache:key:filesso the key follows your lockfile, and a changed lockfile gets a fresh cache. - Set
policy: pullon jobs that should only read, such as test jobs on feature branches, so they never write. - Pin dependency versions. GitLab notes that clearing a cache forces fresh downloads, which can pull unreviewed upstream releases.
- Run release builds from a clean cache on a schedule and compare the output.
test:
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
policy: pull
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a dependency inventory lists exact versions, which is what you want to compare when a cache is cleared.
Safeguard's dependency and SBOM scanning builds that inventory, so a changed package between two builds shows up. Try a free scan at https://gold.safeguard.sh/scan.
Quick check
Does a separate cache cost speed?
Somewhat, since the first pipeline on each side builds its own cache. The cost is small next to the risk of a poisoned release build.
Can I trust a cache hit as proof the files are good?
No. A hit shows the key matched, not that the contents are clean.
Sources
- GitLab Docs: Caching in GitLab CI/CD, fetched 19 October 2026.
Last reviewed: 19 October 2026.