Skip to content
Recovery (offline break-glass)

Recovery (offline break-glass)

leapmux recover is the offline break-glass command tree. It operates directly against the Hub’s database and on-disk encryption key file — no running Hub, no network call, no login. You run it on the machine that holds the Hub’s data directory, typically as the same OS user that runs the Hub.

Every other administration task — users, sessions, workers, OAuth providers, captcha, rate limits, instance settings, API tokens, delegation tokens — runs online, authenticated, over RPC with leapmux control admin ..., or from the Preferences dialog’s administration panels.

Warning: Because leapmux recover writes straight to the database, anyone who can run it has full control over the Hub’s data. That is exactly its purpose — break-glass — and its entire surface is four groups. Protect the data directory and the hosts that can reach it. There is no per-command authentication.

The tree

leapmux recover bootstrap create-admin   # refuses when any admin exists
leapmux recover password reset           # --id | --username, prompts for the new password
leapmux recover db          path | version | migrate
leapmux recover encryption-key rotate | remove | reencrypt | rotate-pepper

Running leapmux recover with no group fails, states that a group is required, and prints the root usage. Help works at every level (--help, help); any command name can be shortened as far as it stays unambiguous.

Locating the data: --data-dir and --config

Every command that touches data resolves the database and encryption key through two common flags:

FlagTypeDefaultPurpose
--data-dirstring(empty)Hub data directory. Empty falls back to ~/.config/leapmux/hub.
--configstring(empty)Path to a Hub config file; loads its storage settings so the command targets the same backend the Hub uses.
  • With --config, storage settings come from the config file; an explicit --data-dir overrides its DataDir.
  • Without --config, a minimal config is built from --data-dir.
  • The SQLite database defaults to {DataDir}/hub.db; the encryption key file to {DataDir}/encryption.key.

Tip: If your Hub runs on Postgres or MySQL, always pass --config /path/to/hub.yaml. Without it the CLI builds a SQLite-only config and would operate on {DataDir}/hub.db instead of your real backend.

Commands that need only the key file or config path — not a live database connection — accept only --data-dir: db path, encryption-key rotate, and encryption-key rotate-pepper.

bootstrap create-admin

Creates the first administrator on an empty hub — the one identity operation that cannot require an authenticated admin to already exist.

leapmux recover bootstrap create-admin --username alice
# (prompts for the password)

The created user is always an administrator. The command refuses once any admin exists, and it points you at control admin user create --admin instead.

Every later user — admin included — is created online through control admin user create.

password reset

Resets a user’s password with the hub stopped — the break-glass path for a hub whose only admin forgot their password. Reach for it when the hub cannot serve; while the hub runs, leapmux control admin user reset-password does the same work over RPC and needs an administrator login.

leapmux recover password reset --username alice
# New password: (no echo)
FlagDescription
--id / --usernameExactly one is required.
--passwordNew password; prompted (no echo) when omitted. Fails when you omit the flag and stdin is not a terminal, because there is nothing to prompt.

On success the password is updated, every session for the user is revoked, and all their API and delegation tokens die with them (durable revocation events are written in the same transaction, so a running hub picks the revocation up on its next watcher sweep). The command reports the user it reset, by username and by ID, and states that it revoked the sessions.

Passwords are 8–128 printable ASCII characters, spaces included (see Password requirements).

encryption-key — encryption keys

The encryption key ring is a file (default {DataDir}/encryption.key, mode 0600) holding versioned XChaCha20-Poly1305 keys plus a dedicated token pepper. The highest version is the active key used for all new encryption; older versions remain only to decrypt old data. For the full keystore model and backup guidance, see Encryption & Data.

Note: The API-token / delegation-token pepper is a dedicated, stable secret stored in the key file but independent of the key ring, so rotate, reencrypt, and remove never invalidate tokens. To deliberately invalidate every API and delegation token, use rotate-pepper.

Note: rotate and rotate-pepper use --data-dir only; reencrypt and remove open the store and accept both --data-dir and --config.

encryption-key rotate

Generate a new key version and make it active. It does not re-encrypt existing data. The key file must already exist (run the Hub once to auto-generate it). The command reports the version it added, and it tells you to restart the hub and then to run leapmux recover encryption-key reencrypt.

encryption-key reencrypt

Re-encrypts every secret not already under the active key version — OAuth provider client secrets, OAuth access/refresh tokens, and hub-settings secret halves. Run after rotate and a hub restart.

encryption-key remove

FlagDefaultDescription
--version0Key version to remove (must be >= 1).

Refuses the active version, an absent version, or a version that still encrypts anything (...; run 'leapmux recover encryption-key reencrypt' first). Always reencrypt after a restart, then remove.

encryption-key rotate-pepper

FlagDefaultDescription
--yesfalseRequired confirmation — this invalidates all API and delegation tokens.

Regenerates the token pepper. The key ring is untouched. Restart the hub to apply, then re-issue tokens online with leapmux control admin api-token issue --hub <url>.

The rotation runbook:

leapmux recover encryption-key rotate              # adds version 2, makes it active
# ... restart the hub so it writes new secrets under version 2 ...
leapmux recover encryption-key reencrypt           # rewrites all old secrets to version 2
leapmux recover encryption-key remove --version 1  # once nothing references version 1

db — database utilities

Opening the store auto-applies pending migrations, so a normal hub start already migrates the schema. These commands confirm state, find the file, or roll to a specific version where supported.

db path

Prints the resolved SQLite database path. --data-dir only. (Always the SQLite path; on Postgres/MySQL use your database server’s tooling.)

db version

Current schema version: 1
Latest available version: 1

db migrate

FlagDefaultDescription
--version-1Target migration version (-1 for latest).

Mainly useful for down-migrating (where the backend supports it) or as a confirmation — opening the store already migrates up.

leapmux recover db migrate --config /etc/leapmux/hub.yaml

Related chapters

Last updated on