Safeguard
Supply Chain•

Who should be allowed to write to a Bazel remote cache?

Let only trusted CI write to a shared Bazel remote cache and make developers read only. Here is the flag, the reasoning and a simple rollout plan.

Safeguard Security Team
4 min read

Only your trusted CI system should write to a shared Bazel remote cache. Developers and pull request builds should read from it. Bazel's own documentation says to take care over who can write, and suggests allowing only CI. Read only access is set with one flag.

What the cache holds

A remote cache stores two things: an action cache, which maps action hashes to result metadata, and a content addressable store of output files. It also keeps stdout and stderr for every action. Anyone who can write to it can influence what other people's builds receive, because a cache hit means Bazel uses the stored output instead of building.

Bazel's docs also point out that the cache holds your binaries, so it needs to be secure.

The risk in one sentence

A bad entry in a shared cache affects everyone who hits it. The sandboxing documentation says this directly: incorrect cache reuse creates problems in remote caching, and wiping the whole cache is not a practical fix.

Who gets which permission

ActorReadWriteWhy
Protected branch CIYesYesControlled environment, reviewed code
Pull request CI from forksYes or noNoUntrusted code should never seed the cache
Developer laptopsYesNoSpeed without the ability to poison
Release buildsOptionalNoPrefer a clean, fully verified build

This table is a recommendation, not a Bazel rule. The product only provides the switches.

The settings

To read and write, point at the cache. To make a client read only, add one more flag.

build --remote_cache=https://cache.example.internal
build --remote_upload_local_results=false

You can also exclude specific targets by tagging them with no-remote-cache, which is useful for anything that embeds secrets or machine specific data.

Rollout plan

  1. Put the cache behind HTTPS and authentication. Basic auth sends credentials in plaintext, so only use it over HTTPS.
  2. Give CI a write credential stored as a protected secret, available only to protected branches.
  3. Ship a shared .bazelrc that sets read only for everyone else.
  4. Log who wrote what where your cache server allows it.
  5. Rehearse deletion. Bazel's docs list creating a clean cache after poisoning as a reason to delete content, and note you cannot tell which build produced an entry, so the realistic response is to clear it all.

Cloud storage keys

If you use an object store, the docs warn that anyone holding the service account key can read and write arbitrary data in the bucket. Treat that key like a deploy credential.

Where Safeguard fits

Safeguard can inventory the dependencies your repository declares through SBOM and dependency scanning, and reachability analysis helps you decide which findings matter first. You can try a free scan on a repository to see what it finds. Check coverage for your specific build files before relying on it.

Try it yourself

Click through the pull request gate and note where a policy can stop an untrusted change before it reaches shared state.

Click through it at your own pace, or open it full screen.

Quick check

Does read only mode stop a developer from being served a bad entry?

No. It stops them from writing one. Reads still return whatever is in the cache, so protect the write path.

Can I tell which build created a cache entry?

Bazel's documentation says there is no way to distinguish which output belongs to a specific build when deleting. Add logging on your server if you need provenance.

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.