The backd CLI
backd, the command line for developers and administrators: the project tools on CONFIG_DIR, and a running backd's admin API for users, keys and data.
backd ships two binaries. backd, this page, is the command line for developers and administrators: the project tools that need only CONFIG_DIR (templates, checks, rules tests, types), and the commands that manage a running backd through a realm’s admin API, as an administrator. It never opens MongoDB and never runs Deno, so it needs no database credentials, and every change it makes goes through the same checks as any other admin request, including network restrictions. It runs on Linux, macOS and Windows; install it from the release archives.
backd-server runs the server roles (serve, worker, executor, egress, provision) and the tools that work on MongoDB or run Deno directly, such as bootstrap, which creates a realm’s first administrator, and functions build. Both images carry both binaries.
Install
Download the backd archive for your system from the releases and put the binary on your PATH:
| System | Archive |
|---|---|
| Linux, macOS | backd_<version>_<linux|darwin>_<amd64|arm64>.tar.gz |
| Windows | backd_<version>_windows_<amd64|arm64>.zip |
checksums.txt lists the SHA-256 of every archive (see Verifying a release). With Go installed, go install github.com/fernandezvara/backd/cmd/backd@v<version> builds the same CLI. backd version prints what you have. Both container images carry the CLI too, for docker compose exec backd backd whoami.
Conventions
- Every value is a flag. There are no positional arguments:
backd user create --realm blog --email ada@example.com.--realm(and--email,--name, …) are required where the command needs them, and--urlpicks the server (below).backd <command> --help, orbackd <command> help, lists a command’s flags;backd helplists the commands. - Exit codes.
0on success (and after help);1when the command ran and failed (a server error, a wrong password, a missingCONFIG_DIR);2when it was invoked wrongly (an unknown command or flag, a missing or invalid flag value). Scripts can tell the two failures apart. - Versions. The CLI sends its version in its
User-Agent(backd/<version>). When the server runs another one, an authenticated admin command prints one line on standard error,warning: the server runs a newer backd than this CLI (…); update the CLI(oran older backd), and carries on: a difference is never refused. The server never states its version. A CLI built from a working tree isbackd/dev, and a released server outside dev mode refuses it with403 dev_client_refused: use a released CLI against a released server. See the security model. - Output. Help and results go to standard output; warnings, errors and prompts go to standard error, so
KEY=$(backd apikey create --realm blog --name ci)captures only the key.
Local and remote commands
| Command | Works on | Needs |
|---|---|---|
backd template, backd databases, backd rules test | CONFIG_DIR | CONFIG_DIR |
backd types | CONFIG_DIR, or --from <url> | CONFIG_DIR, or the running instance |
backd config check|fingerprint, backd functions types | CONFIG_DIR | CONFIG_DIR (config check also applies the instance limits set in the environment) |
backd login, backd logout, backd whoami, backd account … | A running backd | Its URL |
backd user …, backd apikey …, backd data check|checks|transfer|assign-org, backd orgs list|show|create|set-slug|owned|delete|reactivate|members|add-member|invite|invitations|revoke-invitation|assign-owner|claims-set|sso|sso-set|sso-delete|sso-required-off, backd push devices|remove-device|sends|test|web-keys, backd audit …, backd secret set|create|rotate|list|delete, backd encrypt status|rekey|migrate, backd functions invoke|history|logs|jobs|cancel|rerun|schedules|pause|resume, backd triggers status|gaps|resolve, backd storage check|usage|reconcile, backd export, backd compliance scope, backd consents notify|record, backd app-config get|set|reset|history|rollback | A running backd, through the admin API or the function’s own route | Its URL, and a stored session or BACKD_API_KEY |
backd export-decrypt | An export package | The field keys |
backd version | Nothing | Nothing |
What works on MongoDB directly is backd-server’s: the roles, bootstrap, functions build, secret rotate-key, the break-glass user mfa-reset, offline export and import, and triggers rescan.
The first administrator
Administrators are users holding an admin role: a role with admin: true in realm.yaml. The template (backd template realm) declares one, named admin:
roles:
admin:
description: Manages users, invitations and API keys
admin: true
Once the realm is provisioned, create its first administrator with backd-server bootstrap, where backd runs, with the same CONFIG_DIR and MONGO_URI:
docker compose exec backd backd-server bootstrap --realm blog --email ops@example.com
# Password:
# Repeat password:
# created ops@example.com (id d3c9ljp8hc2g00b6s1m0) with the admin role "admin" in realm blog
- If
realm.yamldeclares several roles withadmin: true, choose one with--role. A role that opens only some areas can’t be the first administrator’s: it can’t manage the rest. - After the first administrator, others are created by an administrator, through the API.
- The password follows the realm’s password policy. It is read from the terminal without echo, or as the first line of standard input.
- To keep the assignment if the realm is ever rebuilt from its config, also list the email under the role’s
usersinrealm.yaml.bootstrapreminds you when it isn’t listed.
At startup, backd warns about each realm that declares no admin role, or whose admin roles nobody holds.
Your own sign-in security
backd account manages the signed-in user’s own second factor with the session backd login stored (an API key is not a person). Each change asks for a fresh proof: the authenticator code if the user has one, else the password.
| Command | What it does |
|---|---|
backd account mfa-status | Whether two-step verification is on, and the recovery codes left |
backd account mfa-enable | Sets an authenticator app up (QR code, first code) and shows the recovery codes once |
backd account mfa-disable --yes | Turns it off (refused for a role that requires it) |
backd account recovery-codes | Replaces the recovery codes, shown once |
backd account passkeys-list | Lists your passkeys |
backd account passkeys-remove --id <id> | Removes one (it ends the sessions it opened) |
There is no passkey sign-in in the terminal. A passkey is signed by an authenticator that only a browser or an app can talk to, and handing the terminal’s sign-in to a browser would teach people to approve prompts they did not start (the pattern phishing uses). So backd login --strategy <name> answers this method needs a browser or an app for a strategy that starts with a passkey, or that asks for one after the password, and the realm’s other strategies keep working. The terminal lists and removes passkeys (passkeys-list, passkeys-remove); adding one is done on the realm’s account page or in its app. A user whose only second proof is a passkey cannot give a fresh proof from the terminal either (a password is not enough once a passkey exists), so removing one from the terminal needs the authenticator code too; otherwise use the account page.
backd apikey create asks for the same proof when it runs with a session: an administrator’s key outlives the session and bypasses MFA, so a person confirms it. With BACKD_API_KEY set there is nobody to ask.
Logging in
backd login --realm blog --url https://api.example.com
# Email: ops@example.com
# Password:
# logged in to realm blog on https://api.example.com as ops@example.com (session expires at … at the latest)
backd whoami --realm blog
# ops@example.com (id d3c9ljp8hc2g00b6s1m0) on realm blog at https://api.example.com; roles: admin
backd login signs in through /_auth/login, like any user, and keeps the session for the following commands. It is an ordinary session: the realm’s idle timeout, maximum lifetime, login throttling and the user’s login_networks all apply, and it shows up in the user’s session list. backd logout --realm blog ends it on the server and forgets it.
- The second step. A user with a second factor is asked for its code after the password (
Code from your authenticator app (or a recovery code)); a user in a required role who has none sets one up in the terminal: the command shows a QR code made of block characters, theotpauth://address and the secret to type in, asks for the first code, and shows the recovery codes once (on a terminal it waits until you have saved them). The code is read from the terminal or from the next line of standard input, after the password. --strategy. The strategy to sign in with. Without it, the only strategy that starts with the password is used; with several, the command asks for one on a terminal and otherwise names them and stops.backd account strategies --realm bloglists the realm’s strategies and their methods, without signing in (for the template,backd login --strategy admin_passwordis the administrators’ one: password and code). A strategy with several steps asks for each code in turn.--magic-link.backd login --realm blog --email ops@example.com --magic-linkasks for a message instead of a password (the realm needsmagic_link) and then for the 6-digit code in it.- Server:
--url, else theBACKD_URLenvironment variable, else the server of the last login. - Email:
--email, or a prompt. When standard input isn’t a terminal,--emailis required and the password is the first line of standard input. - Sessions are stored per server and realm in
~/.config/backd/credentials(%USERPROFILE%\.config\backd\credentialson Windows), or$XDG_CONFIG_HOME/backd/credentials, or the file named byBACKD_CREDENTIALS. The file is created readable only by you, in a directory only you can open. Anyone who can read it can act as you until the sessions expire, so log out on shared machines. - TLS:
backdverifies the server’s certificate against the system’s CAs. For a private CA, such as the local stack’s, pointBACKD_CA_CERTat its PEM file. Logging in over plain HTTP to anything butlocalhost, a loopback address, or a host name without dots (a container on a private network, such ashttp://backd:8080) prints a warning: the password would travel unencrypted.
Using an API key instead
When BACKD_API_KEY is set, backd user and backd apikey send that key instead of a stored session. It must be an API key with the admin role. This suits automation that can’t log in interactively:
BACKD_URL=https://api.example.com BACKD_API_KEY=$ADMIN_KEY backd user list --realm blog
Errors
Commands print the API’s error code and message, with a hint when there’s something to do:
| Answer | Usual cause |
|---|---|
401 with a stored session | The session expired, was revoked (a password change revokes the others), or isn’t accepted from this network: log in again |
403 forbidden | The user has no admin role, or the key has the data role |
404 not_found on admin commands | The realm doesn’t exist or has auth disabled, or the admin API isn’t reachable from this network (admin.allowed_networks, or a proxy rule such as the production reference’s ADMIN_ALLOW_FROM) |
Every command
backd help lists the same commands in the same groups; backd <command> --help shows one command’s flags and ends by saying whether it needs a running server. backd-server’s commands have their own page.
Project — local, on CONFIG_DIR only, no running server (see also the quickstart):
| Command | Purpose |
|---|---|
backd template project|realm|database|function|email-capture | Create config files under CONFIG_DIR: a whole project, or a realm, database, function or dev email function inside it (see Starting from a template) |
backd config check, backd config fingerprint | Validate CONFIG_DIR as startup would, or print its fingerprint (see Deploying config) |
backd rules test | Run each collection’s rules.test.yaml against its rules:, without a database (see Testing rules) |
backd databases [--collections] | Print the MongoDB databases (or collections) the config uses, one per line (needs only CONFIG_DIR; see least-privilege deployments) |
backd types | Generate a realm’s TypeScript types (see Typing and OpenAPI) |
backd openapi | Generate a realm’s OpenAPI 3.1 document (see OpenAPI) |
backd export-decrypt --from <package> --out <dir> --field … | Open the encrypted fields of an export package with their keys, offline: no server, no database |
Account — your own sign-in, on a running backd:
| Command | Purpose |
|---|---|
backd login --realm <realm> | Sign in to a running backd as an administrator and keep the session (see Logging in) |
backd logout, backd whoami | End the stored session, or show who it belongs to |
backd account <command> | Manage your own second factor, recovery codes and passkeys (see Your own sign-in security) |
Administration — a running backd’s admin API:
| Command | Purpose |
|---|---|
backd user <command> | Manage a realm’s users through the admin API: list, create, delete, disable, enable, set-password, reset-link, add-role, remove-role, change-email, verify-email, expire-password, expire-passwords, notify-expired, revoke-sessions, mfa-status, mfa-reset, identities, unlink-identity, networks, owned, export, export-download (see Users and passwords); backd user --help describes each |
backd orgs <command> | Manage a realm’s organizations, members, teams and claims, and their sign-in connections (sso, sso-set, sso-delete, sso-required-off) (see Organizations) |
backd apikey <command> | Manage a realm’s API keys (see API keys) |
backd push devices|remove-device|sends|test|web-keys | See a realm’s push devices and send records, remove a device, show the Web Push keys, and send an audited test push (see Records and test send) |
backd secret set|create|rotate|list|delete | Manage function secrets and field keys (create --type key --generate, or --value key:|env:|file:; rotate --generate|--value|--resume); rotate-key re-encrypts them under a new master key, on MongoDB directly |
backd audit | Print the realm’s audit trail, newest first |
backd data check|checks|transfer|assign-org | Check stored documents against their schemas, move documents between collections, or assign them an organization |
backd storage check|usage|reconcile | Check a realm’s object storage, report its usage, or clean up orphans (see Keeping storage tidy) |
backd export, backd import | Write a realm, database or collections, with their files, as a package, or read one into a realm |
backd functions invoke|history|logs|jobs|cancel|rerun|schedules|pause|resume|types | Call a function through a running backd, see its recent calls, console output and jobs, cancel or re-run a job, and list, pause or resume schedules (see Calling functions, Async jobs); types, the functions’ JSDoc types, is local |
backd files regenerate | Rebuild image versions the documents already hold |
backd compliance scope | What a user’s personal data export covers |
backd consents notify|record | Manage the consents users accept |
backd app-config get|set|reset|history|rollback | The realm’s app configuration: values, history, rollback |
backd triggers status|gaps|resolve | See what the trigger dispatcher did, and close a gap (backd-server triggers rescan re-emits a collection’s changes) |
General: backd help, backd version.