Run pull request builds with the cache option set to local read write and remote read only. Turborepo will download shared artifacts but never upload new ones from untrusted code. Let only protected branch builds use remote read write, so a pull request cannot seed the cache others reuse.
What the flag does
The cache option takes a comma separated list of sources, local and remote, each with a mode: read write, read only, or write only. The default is read and write for both. If a source is omitted, reading and writing are both disabled for it. The reference gives these examples:
# read and write local, only read remote
turbo run build --cache=local:rw,remote:r
# only read local, read and write remote
turbo run build --cache=local:r,remote:rw
# no remote activity
turbo run build --cache=local:rw
# no local cache, only read remote
turbo run build --cache=local:,remote:r
A CI split worth copying
| Job | Setting | Reason |
|---|---|---|
| Pull request from a fork | Remote none, or read only | Untrusted code should not write |
| Pull request from your own branch | Remote read only | Faster, cannot poison |
| Protected branch build | Remote read write | Reviewed code seeds the cache |
| Release build | Clean build, consider force | You want to verify, not trust |
The force flag overwrites existing task caches for a run, which is useful for a release build that should not trust earlier entries.
Why this is a security control
A shared cache works because everyone trusts what is in it. The Turborepo remote caching page warns that remote caching comes with responsibility: cache correctly first, check environment variable handling, and remember that logs are treated as artifacts. A write path from every pull request makes all of those risks larger.
Pair the flag with signing, which makes tampering visible, and with a credential that is scoped so only the protected branch job can write.
Steps
- Decide which jobs may write. Write the list down.
- Set the cache option explicitly in every job script, not once in a shared default.
- Store the cache token as a secret available only to protected branches.
- Enable artifact signing and restrict the signing key to the same jobs.
- Add a periodic clean rebuild of a release candidate and compare.
Mistakes to avoid
- Relying on a default. The default is read and write for both sources.
- Giving every job the same token.
- Printing secrets in task output. Logs are replayed from the cache.
- Assuming a self hosted cache is private by default. Follow the authentication model of whatever server you run.
Quick check
What does omitting the remote source do?
It disables both reading and writing for that source in that run.
Should fork pull requests read the remote cache at all?
That is a risk decision. Reading is lower risk than writing, but if you do not want untrusted code to receive shared artifacts, disable remote for those jobs.
Sources
Last reviewed: 19 October 2026.