Skip to main content
aspect setup bazelrc writes a Bazel rc so that vanilla bazel calls pick up the same configuration aspect <task> injects for itself.
Requires Aspect CLI v2026.39.10 or newer, the release that added the two-rc split, —home and —remote. Pin it in .aspect/version.axl; see version pinning.
An aspect build knows about your configured deployments; a bazel build started from the same shell doesn’t. This command writes the equivalent flags where Bazel finds them. aspect ci bazelrc is an older name for the same command.

Two rcs, two jobs

Which rc it writes depends on where it runs. Either way the importing file gains a try-import line at its top, added once and only if absent, so the file’s own lines come after it and win. A repository rc is shared by everyone who builds the repo, so it names what could be turned on and turns nothing on. A machine rc belongs to one host, so that’s where anything gets enabled.
Nothing machine-specific reaches a repository rc. The credential helper is named by tool name rather than by path, the CI host’s group is left out, and the compact execution log is placed through %workspace%. The file is safe to commit and to use on a colleague’s machine.

What each context gets

With a committed repository rc, the machine rc defines only the CI host’s group, and everything else is enable lines pointing at the repository’s own file. What the repository edited in stays in force, and CI still gets the cache. The committed rc must define the sections those lines name, because Bazel fails on a --config no rc defines. If it doesn’t, the command writes the machine rc it would write with no committed rc, and names the missing section.

What it writes

Every flag sits in a named --config group, so bazel build --announce_rc tells you which group set what. The CI host groups are: Buildkite needs no host tweak, so its rc has no host group. A repository rc also gets an opt-in section per deployment:
Each section chains the common and CI-host groups and whatever tuning its endpoints justify. No section is written for the default deployment, because aspect auth use could change what that means under a committed file.
—config=aspect-cloud works before you’ve logged in. Aspect Cloud’s Bazel-facing endpoints are built into the CLI, so the section is correct on a machine that has never run aspect auth login. The build itself still needs a credential.

Which endpoints it turns on

--remote decides, in the same grammar as aspect build --remote: cache and bes are on unless subtracted with no-cache or no-bes, and exec is off unless named. The full table is in Aspect Cloud local setup. Here the default is auto: Remote execution is never implied, on a runner or off it. Asking for exec where the deployment serves no executor prints a warning and leaves it out.
auto won’t enable an endpoint this machine can’t authenticate to: no ASPECT_API_TOKEN and no login on record. Bazel fails a build when a credential helper returns no token, so the rc leaves that endpoint defined but off. An explicit —remote is honored either way.
Only a machine rc enables anything. Whatever --remote says, a repository rc’s sections stay opt-in.

Authentication

The generated sections name aspect as the Bazel credential helper, which Bazel resolves on PATH. It serves the credential from your aspect auth login and refreshes it as needed, so a vanilla bazel build authenticates with nothing more to set up. The command warns if aspect isn’t on PATH where it runs. If you authenticate with a long-lived token instead, put the helper in your own ~/.bazelrc and set --remote_header there. On a deployment using your own identity provider, CI supplies its own credential helper rather than the aspect one.

Options

Without --force an existing rc is left alone: a repository’s is a starting point the repository owns, and a machine’s may belong to a persistent runner someone set up by hand. A Workflows runner clears ~/.aspect before every job, so there it’s written fresh either way. --omit-bazel-flag names the flag as Aspect spells it, and any =value is ignored:
Set it once per repository in .aspect/config.axl:
.aspect/config.axl
Emptying a group removes it along with the lines that named it. Endpoints, credentials, the --config chains and the runner’s output paths can’t be omitted.
—bes_backend and —bes_results_url can be omitted. Bazel reads the workspace rc before the home rc, so a repository that sends vanilla builds to a different build event backend keeps it with —omit-bazel-flag=—bes_backend. Tasks have their own knob, —bazel-flags:omit, since vanilla bazel and tasks may want different omissions.

On a Workflows runner

The generated rc reflects what the runner’s environment advertises. These are opt-in rather than automatic:
  • Remote execution. Where the runner advertises an executor, the aspect-exec group carries it and nothing enables it. Pass --config=aspect-exec on a vanilla bazel call to use it.
  • Cache compression. Where the runner’s cache accepts compressed blobs, the rc leaves compression to the repository. Where it doesn’t, the rc sets --noremote_cache_compression, because Bazel errors when a repository asks for compression from a cache that lacks it.

Build events from tasks and from Bazel

Tasks don’t read rc files: the CLI starts Bazel with --ignore_all_rc_files and passes the expanded options itself. On a Workflows runner --nohome_rc also keeps ~/.bazelrc out of tasks. Elsewhere ~/.bazelrc is parsed, and when the resulting --bes_backend matches the CLI’s own build event stream, the CLI leaves the streaming to Bazel and logs Not streaming …. The invocation is streamed once either way.