Documentation
Getting started
Guides
On this page
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.
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.
[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.
permissions:
contents: read
id-token: write
steps:
- name: Connect BoringCache once
run: boringcache ci connect --oidc-provider github-actions
steps:
- label: Connect BoringCache once
command: boringcache ci connect --oidc-provider buildkite
version: 2.1
jobs:
connect-boringcache:
docker:
- image: cimg/base:current
steps:
- checkout
- run: boringcache ci connect --oidc-provider circleci
# 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.
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.
boringcache ci run \ --oidc-provider github-actions \ -- your-build-command
boringcache ci run \ --oidc-provider circleci \ -- your-build-command
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.