CLI Reference
The backbuild CLI brings the platform to your terminal: the
zero-knowledge secrets vault, project import, local task automation, and
agent integration, all from one small native binary. This reference
teaches you how the CLI is configured and documents every command group.
Availability
The CLI ships as a single, dependency-free native binary named
backbuild for Windows (x64), macOS (universal), and Linux
(fully static x86_64 and aarch64 builds, so one file runs on any
distribution). The binary is about 1.3 MB with no runtime to install.
Backbuild is in Early Adopter Alpha and a public download page for the CLI is coming soon. If you need the CLI binary for your platform today, request it through the contact page. The desktop app for Windows and macOS is available for download now.
Installation
Installation is the same on every platform: place the binary on your
PATH.
- Unpack the archive for your platform.
- Move the
backbuildbinary (orbackbuild.exeon Windows) into a directory that is on yourPATH. On macOS and Linux,/usr/local/binor~/.local/binare conventional; on macOS and Linux also ensure it is executable withchmod +x backbuild. - Close and reopen your terminal so the shell picks up the new command.
- Verify:
backbuild --version
If the shell reports the command is not recognized, the binary is not on
your PATH yet. On Windows, add the folder containing
backbuild.exe to your user Path environment variable
(Settings, then "Edit environment variables for your account"), then open
a new terminal. On macOS and Linux, confirm the install directory appears
in echo $PATH.
Core Concepts
Five ideas explain almost all CLI behavior. Learn these once and every command below becomes predictable.
Per-repository configuration
The CLI keeps project-level configuration in a
.backbuild-cli/ directory at the root of your repository
(the root is detected from Git, so commands behave the same from any
subdirectory). This is where init and
set-token write, where prove settings live, and where local
task state is stored. Configuration travels with the checkout.
Profiles
Profiles are named per-user slots (stored under
~/.backbuild/) that keep one machine's per-account state
separate, for example work and personal. The
secrets client is profile-aware end to end: every secrets
subcommand accepts --profile NAME, and each profile holds
its own machine identity and vault authorization (see the
Secrets CLI guide). The profile a
command uses is resolved in this order:
- The
--profileflag on the command - The
BACKBUILD_PROFILEenvironment variable - The
defaultprofile
If you never pass a profile, everything happens under
default, so a single-account machine never has to think
about profiles. API tokens are never echoed back in CLI output.
For the secrets client, a profile is more than a name: it holds that
machine's identity and its vault authorization, and it is bound to a single
control plane. That binding is fixed at secrets login time from
the environment you selected (BACKBUILD_API_BASE, otherwise
BACKBUILD_ENV) and frozen into the grant, so one machine can
hold independent grants to several deployments at once, one per profile. See
the Secrets
CLI guide for the full workflow. Profile names may contain letters,
digits, hyphens, and underscores, must start with a letter or digit, and are
at most 64 characters; dots and slashes are rejected.
Token resolution
When a command needs an API token, the CLI looks in this order:
- The per-repository token saved by
set-tokenorinit --token - The
BACKBUILD_API_TOKENenvironment variable
API base
The CLI talks to https://api.backbuild.ai (production) by
default, and stays there unless you select another environment yourself.
To point it elsewhere, set BACKBUILD_API_BASE to a full base
URL, or BACKBUILD_ENV to an environment name; an explicit
setting always wins. The CLI never changes environments based on your
working directory or git branch name, so the target is predictable on any
machine.
Exit codes and strict parsing
Every command follows one contract, so scripts can rely on it:
| Exit Code | Meaning |
|---|---|
0 | Success |
1 or 2 | The operation failed: bad input, a missing prerequisite, an API failure, or an unreachable network |
2 | Usage error: unknown option, unknown command, or surplus arguments |
Success is always 0 and usage errors are always
2; whether a failed operation exits 1 or
2 varies by command family, so scripts should branch on
zero versus non-zero unless a command documents a finer contract
(prove ci does, below). Argument parsing is strict: unknown
options, unknown commands, and surplus positional arguments are rejected
rather than silently ignored. --help (or -h)
works globally and per command; --version, -V,
and version print the version.
Authentication with an API Key
The supported way to authenticate the CLI is with an API key minted in the app. After this section you will have a working authenticated CLI in under two minutes.
- In the app, open your API keys settings and create a key. Give it a descriptive name; the key value is shown once, so copy it then.
- Store it in the CLI with a secure hidden prompt (the value is typed twice and never appears on screen or in shell history):
backbuild set-token
For non-interactive environments such as CI, set the key in the
BACKBUILD_API_TOKEN environment variable through your CI
system's secret store instead. Because API keys work everywhere and need
no browser, they are the right choice for headless servers, SSH boxes,
and containers.
Treat an API key like a password: never commit it to a repository, and delete it from the app the moment it may have been exposed; deletion cuts off the key's access immediately. Create a separate key for each machine or automation so revoking one never disturbs the rest.
Configuration Commands
backbuild init
Initialize or update the per-repository configuration. Values you omit
(or pass empty) are left untouched, so init never clobbers
existing configuration.
backbuild init --api https://api.backbuild.ai | Option | Description |
|---|---|
--api | API base URL |
--token | API bearer token (or set BACKBUILD_API_TOKEN, or prefer set-token for a hidden prompt) |
backbuild set-token
Securely prompt for and save your API bearer token in the per-repository
configuration. The prompt is hidden and asks twice to catch typos; pass
--token only where an interactive prompt is impossible.
backbuild set-token Secrets Vault
The secrets command group is the CLI client for the
zero-knowledge Backbuild Secrets vault. Secret values are decrypted
locally on your machine; the platform only ever returns ciphertext. This is
the command surface; for the full workflow (machine identity, the
authorization ceremony, replacing .env files, profiles across environments,
CI patterns, and troubleshooting) read the
Secrets CLI guide.
| Command | Description |
|---|---|
secrets keygen [--force] | Generate this machine’s identity: a hybrid post-quantum encryption keypair (X25519 with ML-KEM-768) and signing keypair (Ed25519 with ML-DSA-65), with both secret keys sealed in the OS keystore. Prints the fingerprint. --force rotates the identity and invalidates its old grants. login bootstraps one automatically. |
secrets status | Local only: print the profile, its machine fingerprint, and whether the sealed key is present. Exits non-zero if the profile has no identity. |
secrets login | Authorize this machine for one vault through the browser consent ceremony (device flow). Seals a 30-day service key and records the granted vault id(s) and expiry. The control plane is fixed at this moment from BACKBUILD_API_BASE/BACKBUILD_ENV. |
secrets get [--vault ID] [--field NAME | --name NAME] [--reveal] [--json] | Fetch and locally decrypt a vault’s items. The listing masks values. Printing values is a reveal the vault owner approves from the app (the command waits up to five minutes): --reveal shows the listing’s values, --field/--name NAME prints one value matched case-insensitively against a field label, and --json emits a JSON array of items. --reveal is required for --field, --name, and --json. |
secrets set --name NAME [--vault ID] | Create or update (upsert by title) a single-field secret; the value is read from stdin, never from arguments. Projects under secrets run as NAME. Requires a read-write grant. |
secrets copy --from-profile SRC --to-profile DST [--from-vault ID] [--to-vault ID] [--dry-run] | Faithfully copy every item from one vault to another, re-sealed under the target key, preserving titles, field labels/values/types, and categories. --dry-run lists what would move and writes nothing. SRC needs a read grant, DST a read-write grant. Refuses copying a vault onto itself. |
secrets run [--vault ID] [--require NAME]... -- COMMAND [ARGS...] | Run COMMAND with vault secrets projected into its environment for that process’s lifetime only; nothing touches disk. Use -- to separate the child command. Each --require NAME makes the run exit 1 without starting COMMAND when that variable would be missing (see Refuse to start without the secrets you need). On Windows it refuses a command that resolves to the WSL launcher, whose environment the secrets would not reach. |
secrets sign [flags] ARTIFACT | Sign an Android .aab/.apk with a keystore held in the vault (details below). |
secrets export [--vault ID] [--format dotenv|shell|json] | Print items as environment assignments to stdout in plaintext. Prefer secrets run; use export only for tools that cannot read environment variables. |
secrets logout [--yes] | Remove this machine’s authorization for the profile (identity, sealed keys, and grant). --yes skips the confirmation. To end a lost machine’s access from the other side, a vault owner revokes its grant (see the Secrets CLI guide). |
Every secrets subcommand accepts --profile NAME
(see Profiles). The secrets client requires an
operating system secure keystore and refuses to run without one; machine
keys are never written as plaintext files. Two additional headless helpers,
secrets seal-item and secrets unseal-item, exist
for on-demand containers and are driven by the platform, not run by hand.
How secrets project into the environment
secrets run and secrets export turn each vault
field into one environment variable. The name joins the item's title and the
field's label as TITLE_LABEL, uppercased, with every
non-alphanumeric character replaced by an underscore and a leading underscore
added if the result would start with a digit (so a field labelled
api key on an item titled Stripe becomes
STRIPE_API_KEY). Two
guards run at this step: names that control a program’s loader or shell
(PATH, IFS, LD_*, DYLD_*,
BASH_FUNC_*, NODE_OPTIONS, PYTHONPATH,
GIT_SSH, and similar) are refused rather than injected, and a
value containing a newline or control byte is refused, so vault content can
never hijack the process you launch. Refusals are reported as warnings and
the safe variables are still set.
backbuild secrets sign
Sign an Android app bundle or package with a keystore that lives in the vault. The keystore is written to a private, owner-only file only for the duration of the run and is overwritten and removed afterward, including on interrupt; the keystore password reaches the signing tool by environment-variable name, never on the command line. The produced signature is verified and the certificate SHA-256 is reported; if verification fails the command refuses and leaves the artifact untouched.
# Reads vault fields MYAPP_KEYSTORE_B64, MYAPP_KEYSTORE_PASSWORD, MYAPP_KEY_ALIAS
backbuild secrets sign --app MYAPP ./app-release.aab | Option | Description |
|---|---|
--app NAME | Prefix the default field names with NAME_ (for example MYAPP_KEYSTORE_B64) |
--keystore-field F | Vault field label holding the base64 keystore (default KEYSTORE_B64) |
--password-field F | Vault field label holding the keystore password (default KEYSTORE_PASSWORD) |
--alias-field F | Vault field label holding the key alias (default KEY_ALIAS) |
--alias NAME | Key alias to sign with, overriding the alias field |
--out PATH | Write the signed artifact to PATH instead of signing in place |
--vault ID | Vault to read from on a multi-vault grant |
The field names above are vault field labels as listed by
secrets get, resolved directly rather than through the
environment projection; an ambiguous match (the same label on two items) is
an error, because a signing identity cannot be taken back once an artifact is
published.
Project Import
backbuild import-project
Import an existing project (specs and code) into Backbuild using AI-assisted analysis over a live connection.
# Import the current directory
backbuild import-project
# Import a specific path
backbuild import-project --project-path ./my-project
# Dry run to see what would be imported
backbuild import-project --dry-run | Option | Description |
|---|---|
--project-path | Project root directory |
--project-name | Name of the project |
--project-description | Project description |
--analysis-depth | shallow or deep (default: deep) |
--exclude-specs | Exclude spec files |
--exclude-code | Exclude code files |
--dry-run | Show what would be imported without starting |
Task Automation
The task commands drive a per-repository task workflow: generate tasks
from project analysis, work them with your local AI coding agents, and
track their states. Task state is kept inside the repository's
.backbuild-cli/ directory, so it travels with your checkout
and these commands keep working offline.
backbuild tasks
List all tasks for the current project. Filter by state with --state.
backbuild tasks
backbuild tasks --state Ready backbuild generate
Run task generators to create tasks from project analysis.
backbuild generate
backbuild generate --generator my-generator backbuild install-default-generators
Install the packaged default task generators into the local generators
directory. Existing generator files are preserved unless
--force is passed.
backbuild install-default-generators
backbuild install-default-generators --force backbuild loop
Run the processing loop: analyze tasks, then execute ready tasks automatically.
backbuild loop backbuild ui
Launch the interactive full-screen TUI: the task list on the left, streaming output in the middle, and the action menu on the right, with batch execution and automatic scheduling built in. In non-interactive terminals it falls back to a plain line-based interface.
backbuild ui backbuild remove <task_id>
Delete a specific task by ID.
backbuild archive <task_id>
Archive a specific task by ID.
backbuild archive-completed
Archive all tasks in the Complete state.
backbuild check-completion
Run the task completion checker on imported tasks.
# Check all tasks in ImportAnalysis state
backbuild check-completion
# Check a specific task
backbuild check-completion --task-id abc123
# Check tasks in a different state
backbuild check-completion --state Analyzing | Option | Description |
|---|---|
--task-id | Check a specific task by ID |
--state | Check tasks in a specific state (default: ImportAnalysis) |
Agent Integration
backbuild setup-codex
Auto-install the OpenAI Codex CLI for use with the agent task harness.
backbuild setup-codex backbuild codex-login
Run codex login to authenticate with a ChatGPT plan.
backbuild codex-login backbuild agent-relay serve
Subscribe this machine to the AI-assistant agent relay and run pushed
assistant jobs locally with your own claude,
codex, or gemini CLI.
backbuild agent-relay serve --device-id my-workstation | Option | Description |
|---|---|
--device-id | Identifier for this device (required) |
--profile | Stored account profile to run under |
--no-reconnect | Exit instead of reconnecting when the relay connection drops |
Local Agent Gateway Registration
The gateway command group manages how the Chromium-based
browsers on this machine (Chrome, Chromium, and Edge) find the program that
serves the Backbuild local agent
gateway, so the Backbuild browser extension can reach it. Registrations
are per user. The gateway ships with the browser extension, which is coming
soon, so these commands matter mainly to early-access setups: they check a
machine's registrations and point the browsers at a gateway program you name.
# Report each browser's registration
backbuild gateway status --host /opt/backbuild/gateway
# Register a gateway program (an absolute path)
backbuild gateway register --host /opt/backbuild/gateway
# Remove that registration again
backbuild gateway unregister --host /opt/backbuild/gateway | Command | Description |
|---|---|
gateway status [--host PATH] | For each browser, report whether it is not registered, registered to this program, registered to this program with an out-of-date manifest, registered to another Backbuild install, registered to a program that no longer exists, or registered to another program. Exits 2 when a registration could not be read, which is never reported as not registered. |
gateway register --host PATH [--replace-foreign] | Register the program at PATH for every installed browser, reporting each one (a browser that is not installed is skipped). This release of the CLI does not contain the gateway itself, so --host is required. An existing registration from another Backbuild install is kept, and one naming a program that no longer exists is replaced. A registration that belongs to another working program is left alone, and the command exits 1, unless you pass --replace-foreign; the replaced registration is kept so it can be put back. |
gateway unregister [--host PATH] | Remove only the registrations that name PATH, and put back a previously kept registration whose program still exists. Registrations that belong to anything else are left alone. |
--host must be an absolute path; a relative one is a usage error.
register and unregister exit 0 when every
browser reached the intended state and 1 when one did not.
Android Test Containers
The android command group drives an Android test container:
install-apk, start-app, input,
ui-dump, screenshot, and logcat.
Every subcommand requires --session <uuid>.
backbuild android screenshot --session SESSION_ID
backbuild android logcat --session SESSION_ID Formal Verification (Prove)
Backbuild Prove is coming soon and is available for
pre-order; see the Prove documentation and
pricing. The prove command group is
documented here so the reference is complete for early access
participants.
backbuild prove run
Scan the project for pf2 annotations and verify them against the HOL kernel. Running bare backbuild prove is equivalent.
backbuild prove run
backbuild prove run --project-path ./my-project | Option | Description |
|---|---|
--project-path | Project root directory (defaults to current directory) |
backbuild prove watch
Watch for file changes and re-verify annotations automatically. The project is polled on a configurable interval and re-verified whenever the set of annotations changes.
backbuild prove watch
backbuild prove watch --poll-interval 5 | Option | Description |
|---|---|
--project-path | Project root directory |
--poll-interval | Polling interval in seconds (default: 2.0) |
backbuild prove ci
Non-interactive verification for CI pipelines. Exits with code 0 if all annotations pass, 1 if any fail, 2 on error.
# Text output (default)
backbuild prove ci
# JSON output
backbuild prove ci --format json
# Generate JUnit XML report
backbuild prove ci --junit-xml reports/prove.xml | Option | Description |
|---|---|
--project-path | Project root directory |
--format | Output format: text or json |
--junit-xml | Path to write JUnit XML report |
backbuild prove status
Show project prove status: settings, annotation count, and per-file breakdown.
backbuild prove status backbuild prove settings
View or update project-level prove settings stored in .backbuild-cli/prove.json.
# View current settings
backbuild prove settings
# Change severity mode
backbuild prove settings --severity-mode warn
# Set verification timeout
backbuild prove settings --timeout 120000
# Add an exclude pattern
backbuild prove settings --add-exclude "vendor/**"
# Remove an exclude pattern
backbuild prove settings --remove-exclude "vendor/**" | Option | Description |
|---|---|
--severity-mode | strict, warn, or lenient |
--timeout | Verification timeout in milliseconds |
--max-parallel | Maximum parallel verifications |
--add-exclude | Add a glob pattern to exclude list |
--remove-exclude | Remove a glob pattern from exclude list |
backbuild prove publish
Build a signed certification bundle and publish it for public verification (see Certifications for what a bundle contains and proves).
# --project-id, --name, and --version are required
backbuild prove publish \
--project-id YOUR_PROJECT_UUID \
--name my-library-core \
--version 1.2.0
# Build and inspect the bundle without uploading
backbuild prove publish \
--project-id YOUR_PROJECT_UUID \
--name my-library-core \
--version 1.2.0 \
--dry-run | Option | Description |
|---|---|
--project-id | Backbuild project UUID (required) |
--name | Bundle name, e.g. my-library-core (required) |
--version | Semver version, e.g. 1.2.0 (required) |
--binary | Path to a compiled artifact to bind into the bundle (repeatable) |
--lean4-results | Path to Lean 4 cross-validation results JSON |
--project-path | Project root directory (defaults to current directory) |
--dry-run | Build the bundle and print metadata without uploading or registering |
The publish pipeline:
- Resolve or generate the signing key (Ed25519, stored at
~/.backbuild/bbprove-keys/) - Scan project for verified theorems and source files
- Build a tarball (manifest, theorems, file hashes, binary hashes, Lean 4 results)
- Sign the tarball SHA-256 locally with the private key
- Upload and register, then print the public verify URL
Your private key never leaves your machine. Only the public key and signature are sent to the API.
Environment Variables
| Variable | Description |
|---|---|
BACKBUILD_API_TOKEN | API bearer token (alternative to set-token; ideal for CI secret stores) |
BACKBUILD_PROFILE | Credential profile to use (overridden by the --profile flag) |
BACKBUILD_API_BASE | Override the API base URL (default https://api.backbuild.ai) |
BACKBUILD_ENV | Select an environment by name (for example production or staging) instead of a full URL |
Scripting, CI, and Offline Behavior
The CLI is built to be scripted. The rules you can rely on:
- Exit codes are a contract. 0 always means success and 2 always covers usage errors; treat any non-zero exit as failure.
prove cidefines the finer contract scripts can branch on: 0 all annotations pass, 1 verification failures, 2 errors. - Machine-readable output where it matters.
secrets get --reveal --jsonandprove ci --format jsonemit JSON suitable forjq(secret values print only with the explicit--reveal, after the vault owner approves). - Errors go to stderr. Diagnostics and warnings are written to standard error, so they never corrupt the stdout your script is parsing.
- No hidden interactivity in CI. Authenticate with
BACKBUILD_API_TOKENfrom your CI secret store; nothing will try to open a browser. - Tokens never print, and secret values only print on request. API tokens are never echoed back. Vault values appear in
secrets getoutput only when you pass the explicit--reveal(which is required alongside a--field/--nameselector or--json), or when you runexport, and both wait for the vault owner’s approval;secrets runmasks injected values in its command’s output, which keeps CI logs clean by default. - Offline behavior is honest. Commands that need the network (import, secrets operations against the vault, publish) fail fast with a clear error and a non-zero exit code when it is unreachable. The per-repository task commands keep working offline because their state is local.
Frequently Asked Questions
The terminal says backbuild is not recognized right after I installed it.
The binary's directory is not on your PATH, or the terminal
was opened before you changed it. Add the directory to your
PATH, open a new terminal, and run
backbuild --version.
How do I authenticate on a headless server or in a container?
Use an API key: mint it in the app, deliver it via
BACKBUILD_API_TOKEN or set-token. No browser is
ever required for API key authentication. For vault access from the
secrets client, the authorization step prints a URL and code you can
approve from any browser on any device; see the
Secrets CLI guide.
Can I use my work and personal accounts on one machine?
Yes. For vault access, authorize each account under its own profile
(backbuild secrets login --profile work) and select with
--profile or BACKBUILD_PROFILE;
backbuild secrets status --profile work shows that
profile's machine identity. For API key commands, store each account's
key in its own repository with set-token, or set
BACKBUILD_API_TOKEN per shell.
Where does the CLI store things on disk?
Per-repository configuration and task state live in
.backbuild-cli/ at the repo root; per-user profile data
lives under ~/.backbuild/. Vault machine keys are held in
your operating system's secure keystore, and the secrets client refuses
to run without one. Tokens are masked in all output.
Does the CLI work offline?
Task commands do, because their state is stored in the repository.
Anything that talks to the platform requires connectivity and exits with
a clear error and a non-zero code without it.
See Also
- Secrets from the CLI: the complete vault workflow guide
- REST API Reference: the same platform, over HTTP
- Authentication API: registration, login, OAuth, and session endpoints
- Prove CLI: deeper documentation of the verification commands
- Local Agent Gateway: what the gateway the
gatewaycommands register does