Skip to content
Documentation

Docs / CLI

CLI

Run, save and restore, authenticate, then diagnose from Workspace status to an exact cache tag or entry.

Run builds and manage cache

The CLI is the entrypoint for most teams. Run boringcache onboard once per repo, then use archive mode or the adapter named after your build tool.

Repo config and shorthands

Most projects should start with boringcache onboard. It can authenticate the CLI, set a default workspace, and write .boringcache.toml so the same cache names work across local runs, Docker builds, and CI.

Workflow scanning is opt-in and the default answer is skip; approved proposals are still previewed before writing. Use --skip-workflows or -S to skip workflow discovery and AI-assisted suggestions.

Need terminal-first auth? Use boringcache onboard --email you@example.com. For a new account, add --name and --username or let the CLI prompt.

For GitHub Actions, onboard --github-secrets can set split repository secrets when gh can manage the repo and your BoringCache token can create workspace tokens. For other CI providers, or when those permissions are missing, onboard keeps the repo config path open and gives you the admin handoff.

.boringcache.toml
workspace = "my-org/app"

[proxy]
metadata-hints = ["project=web"]

[entries.bundler]
tag = "bundler-gems"

[profiles.bundle-install]
entries = ["bundler"]

[adapters.bazel]
tag = "bazel-cache"
metadata-hints = ["tool=bazel", "lane=ci"]

[adapters.docker]
tag = "docker-cache"
command = ["docker", "buildx", "build", "."]

To leave files out of an archive save, add an exclude list to that entry. Patterns use the same matching rules as boringcache save --exclude-pattern; commas and spaces are preserved, and .gitignore is not read. Exclusions affect future saves and do not remove local files or filter a previously saved cache during restore.

.boringcache.toml
[entries.build-output]
path = "build"
exclude = ["*.tmp", "scratch/"]

[profiles.build]
entries = ["build-output"]

Use boringcache run --profile build --exclude-pattern '*.log' -- your-build-command to add a pattern for one invocation. Adapter commands such as boringcache cargo --exclude-pattern '*.tmp' build accept the same option for their archive entries. An entry's configured exclusions apply only to that entry; command-line patterns apply to every archive entry selected by the command. Preview the result with --dry-run --json. In GitHub Actions, select the committed profile with cache-profiles.

If your repo already uses a lot of literal tag:path pairs, boringcache audit --write can import them into .boringcache.toml. That is a migration path, not the default getting-started flow.

Common commands

# Archive mode (run/save/restore)
boringcache run -- bundle install

# Docker adapter from repo config
boringcache docker

run

run restores the selected archives, executes your command, and by default saves after a successful command when the credential permits publication.

Archive mode: restore, run, save.

boringcache run --profile bundle-install -- bundle install
boringcache run -- bundle install

Use --entry for one built-in or repo-defined entry, --profile for a named group, and bare boringcache run -- ... when the CLI can infer a known install profile.

Flags

--fail-on-cache-miss Fail before running the child command if cache is missing. Exit code 78.
--fail-on-cache-error Treat cache/backend failures as hard failures. Exit code 78 when cache flow fails.
--no-platform Disable automatic OS/architecture suffixes on tags.
--no-git Disable git-aware tag suffixing.
--force Overwrite existing entries on save.
--save-on-failure Run the save phase even when the wrapped command fails; publication still requires write permission.
--exclude-pattern <PATTERN> Exclude one literal glob pattern. Repeat the flag for multiple patterns so commas and whitespace remain part of the pattern.
--allow-external-symlinks Allow external symlinks in content-addressed layouts. Archive transport leaves symlink handling to tar.

Exit Codes

0 Command succeeded
78 Cache miss or error with --fail-on-cache-miss or --fail-on-cache-error
127 Command not found
N Child process exit code (preserved)

Archive runs are opaque, SHA-verified tar round trips. The tar extractor restores the archive entries; BoringCache verifies the decoded tar and reports the result without inspecting individual files. --allow-external-symlinks applies only to content-addressed layouts and has no effect on archive transport.

save / restore

Use save and restore when cache operations need to happen at different points in the job. Use run to wrap one command.

# Save
boringcache save my-org/app --entry "deps:node_modules"
boringcache save my-org/app --entry "deps:node_modules" --entry "build:dist" --force

# Restore
boringcache restore my-org/app --entry "deps:node_modules"
boringcache restore my-org/app --entry "deps:node_modules" --fail-on-cache-miss

Common save flags: --force, --archive-transport, repeatable literal --exclude-pattern, --no-platform, --no-git, --fail-on-cache-error. Use --archive-transport when a save must not auto-select a native content-addressed layout.

Common restore flags: --fail-on-cache-miss, --lookup-only, --no-platform, --no-git, --fail-on-cache-error.

Archive handling is built into the CLI on every supported platform. BoringCache creates deterministic archives, verifies them before restore, and preserves modification times needed for build freshness without a system tar install.

Smaller commands

auth

boringcache auth --token YOUR_SAVE_OR_ADMIN_TOKEN

Manual setup stores a token locally for day-to-day CLI use. Most projects should still start with boringcache onboard, which handles auth and can seed repo config for you. In CI, prefer a Machine connection with workload OIDC; use split scoped environment variables when OIDC is unavailable. See Authentication.

status

boringcache status my-org/app
boringcache status my-org/app --json

Start here when you need the Workspace-level picture: storage inventory, recent runs, reuse, misses, and tool evidence. JSON identifies itself as workspace_status; it is separate from the runner-local proxy status endpoint.

check

boringcache check my-org/app "deps,build" --json

Check whether specific archive or native-tool tags are ready without downloading them. Use --json for machine-readable status and add --fail-on-miss when a missing tag must fail automation. Without a strict flag, human-mode lookup errors are warnings.

inspect

boringcache inspect my-org/app deps

Inspect one Cache entry by tag or entry ID after check establishes readiness. It shows identity, stored representation, tags, lifecycle, commands, and recent performance; it is not the readiness path for native-tool KV tags that have no Cache entry ID.

sessions / misses / tags / analyze

boringcache sessions my-org/app --json
boringcache misses my-org/app --json
boringcache tags my-org/app --json
boringcache analyze my-org/app --json

Use these narrower Workspace reports after status points to a run, repeated miss, tag, or value question. Their JSON carries a schema version and a named output kind so support tooling does not have to infer the command from the payload.

ls

boringcache ls my-org/app --json

List cache entries. Options: --limit, --json

delete

boringcache delete my-org/app "deps"

Removes the selected cache tags. Backing objects are reclaimed asynchronously.

config

boringcache config list
boringcache config set default_workspace my-org/app
boringcache config get default_workspace

Manage CLI configuration. Options: --json

workspaces

boringcache workspaces --json

List available workspaces.

Authentication

Most projects should start with boringcache onboard, which connects the CLI to a workspace for the repo. Use boringcache login --email you@example.com for account sign-in on a developer machine. CI platforms with workload OIDC can use a Machine connection instead of storing a BoringCache token. If workload OIDC is unavailable, scoped restore and save credentials remain a supported explicit choice.

With CLI and Action 1.32.0 or later, a Machine connection supplies its approved workspace. An explicit workspace must match it. Local and scoped-token runs keep the repository workspace or configured default; an explicit workspace can override it.

For organizations that require SSO, browser approval issues human CLI credentials that expire with the organization SSO grant, up to eight hours. Sign in again to issue a new credential. Use an approved machine credential or workload identity for CI. See organization SSO.

A CI without a native BoringCache adapter can enroll an exact provider profile with --oidc-profile and submit one fresh ID token from a bounded regular file with --oidc-token-file. Run boringcache onboard with --skip-workflows --manual, then approve the printed URL from any browser. Approval can authorize the exact workload to restore and publish, or deliberately keep it restore-only when the identity is shared with untrusted jobs. A failed OIDC path never falls back to a static CI credential and never creates one.

You can start the same transaction from a Workspace by choosing Connect CI. Pick OIDC, explicit scoped restore/save credentials, or local CLI only. GitHub Actions, Buildkite, CircleCI, GitLab.com, and BoringBuild route to a native command with no BoringCache secret: run boringcache ci connect inside the CI job, open its verification URL on any signed-in device, and choose the Workspace. The server delivers the one-time enrollment only to the waiting job and the CLI keeps it in memory while it submits the provider assertion. A registered OIDC issuer or automated setup can still use the explicit one-time value through standard input with --oidc-token-command. Completion posts once without retry and prints no credential or assertion.

GitHub Actions Machine connection
permissions:
  contents: read
  id-token: write
steps:
  - name: Connect BoringCache once
    run: boringcache ci connect --oidc-provider github-actions
Buildkite Machine connection
steps:
  - label: Connect BoringCache once
    command: boringcache ci connect --oidc-provider buildkite
CircleCI Machine connection
version: 2.1
jobs:
  connect-boringcache:
    docker:
      - image: cimg/base:current
    steps:
      - checkout
      - run: boringcache ci connect --oidc-provider circleci
BoringBuild Machine connection
# Run once in a BoringBuild job with id-token: write,
# then approve the printed URL and choose the Workspace.
boringcache ci connect --oidc-provider boringbuild

BoringBuild enrollment is a one-time bootstrap job. Its controller gives that job a short-lived assertion endpoint; BoringCache verifies the exact BoringBuild organization, repository, and connection IDs before creating the Machine connection. After approval, normal native jobs need no repository secret or workflow auth step: the BoringBuild supervisor renews assertions and keeps the private runner-local broker running before repository code starts. Pull requests and other untrusted source contexts are restore-only.

GitLab CI Machine connection
connect-boringcache:
  timeout: 1h
  id_tokens:
    BORINGCACHE_OIDC_TOKEN:
      aud: urn:boringcache:workload
  script:
    - boringcache ci connect --oidc-provider gitlab

After enrollment, providers whose workflow handles activation use boringcache ci run; BoringBuild's supervisor activates the broker before repository code starts. Renewable providers acquire a fresh token at startup and before session expiry. A provider that exposes one fixed token per job can use a native adapter or --oidc-token-env NAME; BoringCache exchanges it once, removes the variable from the broker and wrapped command, and keeps the private broker session no longer than the signed assertion, capped at one hour. Cache, Artifact, and Registry clients receive separate five-minute capabilities, with live connection, binding, product, and publication policy checked each time. Static BoringCache credential variables are removed from every child process, and acquisition, exchange, renewal, or broker failure stops the wrapped command without fallback.

GitHub Actions
boringcache ci run \
  --oidc-provider github-actions \
  -- your-build-command
CircleCI
boringcache ci run \
  --oidc-provider circleci \
  -- your-build-command
GitLab CI
build:
  timeout: 1h
  id_tokens:
    BORINGCACHE_OIDC_TOKEN:
      aud: urn:boringcache:workload
  script:
    - boringcache ci run --oidc-provider gitlab -- your-build-command

Native assertion acquisition is built in for GitHub Actions, Buildkite, CircleCI, GitLab CI, and BoringBuild. GitHub Actions, Buildkite, CircleCI, and BoringBuild can renew assertions; BoringBuild's normal path is supervisor-managed, so workflow authors do not wrap their build with boringcache ci run. CircleCI verifies the signed project, VCS origin, and ref; issued fork assertions or missing source context stay restore-only. GitLab injects the audience-bound token declared by id_tokens; the CLI consumes it once, and GitLab's explicit job timeout determines its lifetime up to BoringCache's one-hour broker cap. GitLab merge-request and fork source jobs remain restore-only. A custom acquisition command must print exactly one fresh OIDC ID token each time it runs. Use a scoped credential or split a job that must run beyond a fixed provider token's bounded lifetime. Wrapped-command standard output is preserved, while broker status is written to standard error.

For manual local auth, use boringcache auth --token .... In CI using scoped credentials, use split tokens and let the CLI pick the least-privileged one that can do the job.

# Restore-only CI job
export BORINGCACHE_RESTORE_TOKEN=...

# Trusted CI job that should also save
export BORINGCACHE_SAVE_TOKEN=...
Operation Token resolution
restore, run restore phase BORINGCACHE_RESTORE_TOKEN → BORINGCACHE_SAVE_TOKEN → BORINGCACHE_ADMIN_TOKEN → BORINGCACHE_TOKEN_FILE → local config
save, run save phase BORINGCACHE_SAVE_TOKEN → BORINGCACHE_ADMIN_TOKEN → BORINGCACHE_TOKEN_FILE → local config
Admin operations such as delete BORINGCACHE_ADMIN_TOKEN → BORINGCACHE_TOKEN_FILE → local config

Read-only adapters: adapters use the restore token and do not publish writes.

Strict writes: write commands fail fast when only a restore token is configured.

Signatures: official Actions enable strict signature verification by default. In other environments, set BORINGCACHE_REQUIRE_SERVER_SIGNATURE=1 or pass --require-server-signature when you want restore to fail closed. Set BORINGCACHE_TRUSTED_WORKSPACE_KEY_FINGERPRINT when you also want to pin the expected workspace signing key.

Keep write tokens trusted: signatures do not replace token separation. If a low-trust job gets a save or admin token, it can still publish poisoned cache tags that trusted jobs may restore later.

Environment Variables

Set these variables to control authentication, defaults, and runtime behavior.

Variable Description
BORINGCACHE_RESTORE_TOKEN Preferred token for restore and other read-only operations in CI
BORINGCACHE_SAVE_TOKEN Preferred token for save and other write operations in CI
BORINGCACHE_ADMIN_TOKEN Preferred token for workspace administration, including token creation and delete operations
BORINGCACHE_REQUIRE_SERVER_SIGNATURE Set to 1 to fail restore when the server signature is missing or invalid. Official Actions set this for you.
BORINGCACHE_TRUSTED_WORKSPACE_KEY_FINGERPRINT Optional ed25519-sha256:... workspace signing key fingerprint for pinned signature verification.
BORINGCACHE_TOKEN_FILE Path to a file containing a token. Useful for mounted secrets in CI.
BORINGCACHE_DEFAULT_WORKSPACE Default workspace when a command does not specify one
BORINGCACHE_API_URL Override the default API endpoint
BORINGCACHE_REGISTRY_HOST Override the default registry host for self-hosted or local environments
BORINGCACHE_NO_GIT Set to 1 to disable git-aware tag suffix behavior

Need help or found something unclear? Open an issue or browse the CLI repo.