From Build Acceleration to Autonomous SDLC: Six Bazel Contributions and a Security Fix
- Resources
- Blog
- From Build Acceleration to Autonomous SDLC: Six Bazel Contributions and a Security Fix
- Blog post by: Yossi Eliaz
- \[23 Sep 2026\]
- Resources
- Blog
- From Build Acceleration to Autonomous SDLC: Six Bazel Contributions and a Security Fix
- Blog post by: Yossi Eliaz
- \[23 Sep 2026\]
- LOADING HEADINGS...
- Six upstream Bazel contributions from our Software Factory were imported to Bazel master through Google’s Copybara workflow.
- Along the way, we found a path-containment flaw in `--experimental_repo_contents_cache`, reproduced it end to end on a shipping Bazel 9.0.2 binary, and reported it privately.
- Google fixed it upstream in c37a6a1bf7f4. The fix is in Bazel 9.3.0rc2; Bazel 9.2.0 still ships the pre-fix logic.
- If you use that flag: upgrade to a build that contains the fix, or turn the flag off until you can.
From Build Acceleration to Autonomous SDLC: Six Bazel Contributions and a Security Fix
From Build Acceleration to Autonomous SDLC: Six Bazel Contributions and a Security Fix
Using an early internal version of Incredibuild’s Software Factory, we landed six upstream Bazel contributions, uncovered a remote-cache path-containment security flaw, and came away with a concrete set of requirements for automated software engineering. A companion to our Bazel series: Part 1, Part 2, and Part 3.
Generating code is getting fast and cheap. Building, testing, validating, and deciding what reaches main is where agents, and people, now stand waiting.
For more than two decades, Incredibuild has focused on one problem: shortening the build-test loop without forcing engineering teams to reinvent how they build software. That began with distributed compilation and grew into caching, CI, testing, telemetry, and build integrity.
AI is moving the bottleneck. When an agent can draft a patch in seconds, the long pole is everything after it: the build, the test run, the evidence, the review. That’s the problem our Software Factory is built to solve. Before pointing it at anyone else’s code, we pointed it at our own products and at the ecosystem around us, and Bazel is a big part of that ecosystem.
TL;DR
Why Bazel was the right proving ground
Bazel models software as a graph of declared work, makes caching and remote execution first-class concepts, and treats reproducibility as part of correctness. Those are the same problems Incredibuild has spent two decades solving from a different layer of the stack. (If you want the full background, start with Bazel, Inside and Out.)
It’s also a demanding target. Bazel’s Remote Build Execution (RBE) model is powerful, but adopting it is a real engineering project: hermetic actions, rule coverage, toolchains, platforms, and REAPI infrastructure all have to line up. And real repositories rarely live entirely inside a clean action graph. They contain nested Make or Ninja builds, custom compilers, test harnesses, scripts, packaging, code generation, and proprietary tools.
Our approach is complementary. Bazel orchestrates the build; Incredibuild provides caching and distributed execution across the existing workload, including the parts that are hard to move to RBE. Teams get faster builds now, while the RBE migration continues on its own schedule.
So Bazel mattered to us twice: as a workload we accelerate, and as a build system we have to understand all the way down to its cache boundaries.
What the Software Factory actually does
The Software Factory isn’t an “agent writes code” demo. It runs the whole engineering loop as a factory line:
goal → plan → isolated task → implement → build → test → inspect → retry → reviewable PROne rule doesn’t bend: automated search and model output can propose patches, run experiments, or return cached results. Test verification and human review keep authority over what merges to main.
Six contributions landed upstream
Six changes from this effort were imported to Bazel master through Google’s Copybara workflow. None of them is flashy. All of them are about the same thing: making automation trustworthy.
| #30365 | Made bazel-distfile.tar reproducible by removing locale-dependent ordering, and made unknown archive types fail explicitly | Determinism | | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | | #30358 | Skipped the SSL tracking-issue mutation step on pull-request validation runs. A PR can validate the monitor, but must never create or update production tracking issues | Authority boundaries | | #30364 | Ignored COMMENTED reviews when computing community-review status, so a comment can no longer erase a prior APPROVED or CHANGES\_REQUESTED decision | Authority boundaries | | #30363 | Parsed certificate expiration independently of host locale, so monitoring no longer depends on an unrelated LC\_TIME setting | Determinism | | #30360 | Corrected the documented BAZEL\_DOC\_TRIGGER\_TOKEN scope to bazel-docs, the repository the workflow actually dispatches to | Correct configuration | | #30359 | Paginated PR-review retrieval and made it fail closed if a later page fails | Complete evidence |
Links to each change: PR #30365 · PR #30358 · PR #30364 · PR #30363 · PR #30360 · PR #30359.
The pattern is the point. Deterministic outputs, complete evidence, clear authority boundaries, and safe failure modes aren’t nice-to-haves for automated software engineering. They’re the difference between an agent you can let run and one you have to babysit. Partial evidence must never be treated as complete evidence.
Then the cache boundary got interesting
As we went deeper into Bazel’s caching architecture, we examined `--experimental_repo_contents_cache`.
The feature restores the output of reproducible repository rules from a remote Action Cache (AC) and Content Addressable Storage (CAS). That’s good for performance, but it moves the trust boundary: cache-supplied metadata now participates in filesystem materialization.
Before the fix, Bazel trusted cache-supplied tree node names without sufficiently enforcing that the resulting path stayed inside the intended external repository directory. A node name containing parent-directory traversal or an absolute path could land outside it.
We didn’t stop at reading source. The Software Factory generated a reproducible, end-to-end test case against a real Bazel 9.0.2 binary. Under the required conditions, a poisoned remote-cache entry caused Bazel to overwrite a pre-existing file outside the repository root, while the build itself still completed successfully.
Who is actually exposed
All three conditions have to hold:
| \--experimental\_repo\_contents\_cache is enabled with a remote cache | The flag appears in a .bazelrc, CI config, or wrapper script | | --------------------------------------------------------------------- | -------------------------------------------------------------- | | Someone untrusted can write to the relevant remote AC / CAS | Review who holds write credentials to your shared cache | | Your Bazel binary predates commit c37a6a1bf7f4 | bazel --version reports 9.2.0 or another build without the fix |
This is not a drive-by internet vulnerability. But that’s exactly why it matters: once cache metadata can steer filesystem writes, anyone who can write to your remote cache is part of your trusted computing base.
We reported the finding privately to the Bazel security team, with the reproduction attached.
Google fixed it upstream
Google’s Bazel team fixed the issue in commit c37a6a1bf7f4, “Improve path validation in remote repository contents cache.” The fix:
That’s the right place for the check: the exact boundary where untrusted cache metadata becomes a filesystem path.
What to do if you use --experimental\_repo\_contents\_cache
1. Find out whether the flag is on. Search every place Bazel options come from:
grep -rn "experimental_repo_contents_cache" \
.bazelrc ~/.bazelrc /etc/bazel.bazelrc ci/ tools/ 2>/dev/null2. Check the exact binary you run, not the one you think you run. With Bazelisk, also check `.bazelversion` and `USE_BAZEL_VERSION`.
bazel --versionBazel 9.2.0 still contains the pre-fix path logic. Bazel 9.3.0rc2 contains the path-containment validation.
3. Upgrade or disable. Move to a Bazel build that contains c37a6a1bf7f4. If your organization can’t deploy a release candidate, disable `--experimental_repo_contents_cache` until a stable release with the fix is available.
4. Treat cache write access as a security boundary, not a performance setting. Know exactly who and what can write to your shared remote Action Cache and CAS.
What this taught us about automated SDLC
Build acceleration runs on structured graphs, deterministic inputs, reusable outputs, process isolation, scheduling, and defined trust boundaries. Those same primitives are the foundation of automated software engineering:
Bazel turns source code into an explicit execution graph. The Software Factory extends the same idea upward: it turns the software development lifecycle itself into a managed graph.
The scorecard
We ran the system against an active open-source project to see whether its architecture holds up against real maintainer feedback, build failures, iterative changes, and security disclosure:
After more than two decades of making builds faster, the next step is making the entire engineering loop faster, from intent to tested, reviewable, evidence-backed software, without giving up the controls that make software trustworthy.
Sources
Yossi Eliaz
#### Shorten Your Builds
Incredibuild empowers your teams to be productive and focus on innovating.
##### Share
Related Blog Posts
[
CI/CD tools Top 7 GitHub Coding Agents in 2026, Ranked by Speed, Quality & Integration Depth \[16 Sep 2026\] ](https://www.incredibuild.com/blog/best-github-coding-agents-2026)
[ Uncategorized The fun part was free. Proving it worked cost $1.96. \[25 Aug 2026\] ](https://www.incredibuild.com/blog/the-fun-part-was-free-proving-it-worked-cost-1-96)
[
CI/CD tools How to Integrate Incredibuild With GitHub Actions for up to 4x Faster Pipeline \[21 Aug 2026\] ](https://www.incredibuild.com/blog/github-actions-large-codebases)
Never run anything twice
#### Shorten Your Builds
Incredibuild empowers your teams to be productive and focus on innovating.
##### Share
Related Blog Posts
[
Dev tools Best practices to create reusable workflows on GitHub Actions \[26 Mar 2025\] ](https://www.incredibuild.com/blog/best-practices-to-create-reusable-workflows-on-github-actions)
[
Build systems, CI/CD tools How to build a successful test automation framework \[17 Mar 2025\] ](https://www.incredibuild.com/blog/how-to-build-a-successful-test-automation-framework)
[
Containers, Dev tools Docker 101: A comprehensive tutorial for beginners \[16 Jan 2025\] ](https://www.incredibuild.com/blog/docker-101-a-comprehensive-tutorial-for-beginners)
[
DevOps Everything you need to know about healthcare software \[24 Aug 2023\] ](https://www.incredibuild.com/blog/everything-you-need-to-know-about-healthcare-software)
[
C++ What is a Virtual Function – And How Can C++ Devs Make the Most of Them? \[21 Dec 2022\] ](https://www.incredibuild.com/blog/what-is-a-virtual-function)
Never run anything twice
Build Acceleration
Build Cache Remove Redundant Execution Distributed Processing Parallelize Task Execution Analytics Uncover Pipeline Bottlenecks CI Runners beta Eliminate CI Queues Coding Agent Sandbox New Ensure Continuous AI Coding Build Guard beta Generate Audit-Ready SBOM Software Compatibility Layer Reduce Windows Compute Costs
Integrations
Industries
Gaming and Simulation Financial Services
use cases
Build Acceleration CI/CD Acceleration SBOM Generation
Resources
Blog
Resource Library
Case Studies
Glossary
Docs
Release Notes
Support
