Admin CLI
A command-line tool shipped with MaestroHub that works directly on its stores, for break-glass access and administrative tasks.
- Ships
- In the release archive
- Commands
- Users · Database · Re-encryption · UNS
- Works on
- SQLite files or Postgres databases
The MaestroHub Admin CLI (admin-cli) is a command-line tool for managing users and performing database operations. It is bundled with MaestroHub and included in the release archive. It provides break-glass access for emergency situations and administrative tasks that require direct database interaction.
Where the CLI finds the stores
MaestroHub keeps every store by one rule: with storage.engine: sqlite (the default) a store is the file <storage.dataDir>/<store>.db (auth.db, connectors.db, uns.db, …), and the generated keys are in <storage.dataDir>/secrets; with storage.engine: postgres a store is the database <store>_db on storage.postgres. The UNS store is a module store like any other (uns.db or uns_db), whichever historian runs. storage.dataDir defaults to ./data, relative to the directory MaestroHub runs in.
The CLI reads the same settings, so tell it about the installation once:
| Flag | What it names |
|---|---|
--config <file> | The context engine's config.yaml: its storage block and UNS historian place every store. The MAESTROHUB_* variables apply as they do to the server. |
--data-dir <dir> | The context engine's storage.dataDir, whatever --config says. |
Without either, the CLI uses ./data under the directory it runs in. Typical installations:
- Binary install:
admin-cli --data-dir ~/maestrohub/data …, or--configthe file you start MaestroHub with. - Docker: run the CLI in the container (
docker exec --user maestrohub <container> admin-cli …): its working directory is the/datavolume, so the default./datais the image's/data/data. Pass--user maestrohub: the image starts as root to make/datawritable and then runs MaestroHub asmaestrohub, so a file root writes there (a new key file, a backup) is one MaestroHub cannot read. If the container was started with--config /config/config.yaml, pass the same--config. - Postgres engine:
--configthe file whosestorage.engineispostgres; the CLI connects to<store>_dbonstorage.postgres.
A store an earlier release kept elsewhere. 2.6 Docker installations kept eleven stores flat in the /data volume, beside the data directory. Until context-platform upgrade apply moves them, the CLI finds a store there too, and says so. A store found in both places is not opened: context-platform upgrade check says which one is current.
Naming a store yourself
A flag that names one store wins over the rule:
-
the user and db commands:
--database <path or URL>(-d), or one of these environment variables, checked in this order:Variable Description DATABASE_URLFull database connection URL or file path DB_URLAlternative connection URL MAESTRO_DATABASE_URLMaestroHub-specific connection URL POSTGRES_URLPostgreSQL connection URL POSTGRESQL_URLPostgreSQL connection URL SQLITE_PATHPath to the SQLite auth store DB_PATHPath to the SQLite auth store When none is set and no auth store is found where the rule keeps it, the CLI connects with the standard
PGHOST/PGPORT/PGUSER/PGPASSWORD/PGDATABASEvariables (PGDATABASEdefaults toauth_db). -
the
reencryptcommands:--db,--dsnand--secrets-dir(below).
Global Flags
These flags can be used with any command:
| Flag | Short | Description |
|---|---|---|
--config | The context engine's config.yaml (see above) | |
--data-dir | The context engine's storage.dataDir (see above) | |
--database | -d | The auth store's path or URL, for the user and db commands |
--verbose | -v | Enable verbose output |
--force | -f | Skip confirmation prompts |
--version | Display version information | |
--help | -h | Display help information |
Commands
User Commands
List Users
Display all users in the system.
admin-cli user list [--limit <number>]
Options:
| Flag | Description | Default |
|---|---|---|
--limit | Maximum number of users to display | 20 |
Example:
admin-cli user list --limit 50
Reset Password
Reset a user's password. This is the break-glass method for emergency access when email is unavailable.
admin-cli user reset-password --email <email> [--password <password>]
Options:
| Flag | Short | Description | Default |
|---|---|---|---|
--email | -e | User's email address (required) | - |
--password | -p | New password | TempPassword2024! |
Examples:
Reset with default temporary password:
admin-cli user reset-password -e admin@example.com
Reset with custom password:
admin-cli user reset-password -e admin@example.com -p "NewSecurePass123!"
Skip confirmation prompt:
admin-cli user reset-password -e admin@example.com -f
After using break-glass reset, instruct the user to change their password immediately after signing in.
Database Commands
Database Info
Display database connection information and statistics.
admin-cli db info
Output includes:
- Database type
- Connection location
- Total user count
Test Connection
Test the database connection and verify connectivity.
admin-cli db test
Use this command to verify your database configuration before running other operations.
Re-encryption Commands
Rotate the AES-GCM encryption key a module encrypts its stored secrets with. These commands re-wrap every encrypted row in place under a new key and update the on-disk secrets file atomically. Signing keys are re-wrapped, not replaced, so every token they signed stays valid.
Use them to move off a key that leaked or is publicly known, for example after context-platform upgrade check or apply prints a SECURITY: warning about a module's key (see Secrets are now encrypted).
| Subcommand | What it re-encrypts | Key file |
|---|---|---|
reencrypt connectors | Connection secrets, in connections and connections_history | connectors_encryption_key |
reencrypt uns | UNS settings secrets, in uns_settings and uns_settings_history | uns_encryption_key |
reencrypt auth | Identity-provider secrets (OIDC client secrets, LDAP bind passwords) and the key that signs personal access tokens | auth_encryption_key |
reencrypt oauth2 | The OAuth2 server's token-signing private keys | oauth2_encryption_key |
reencrypt email | The SMTP passwords of the email configuration | email_encryption_key |
reencrypt fleet_client | The context engine's API key to its Fleet Manager | fleet_client_encryption_key |
reencrypt maestro | Maestro AI provider-account API keys (the Maestro agent is in Beta, on request) | chat_encryption_key |
The reencrypt commands write directly to the module's store. The MaestroHub server must be stopped before you run them, because running both at once will corrupt the database.
Each subcommand finds its module's store the way the user commands find the auth store: --config / --data-dir (see Where the CLI finds the stores). With storage.engine: postgres it rotates the module's <store>_db and writes the new key to <storage.dataDir>/secrets, where the context engine reads it. Take a pg_dump first: a Postgres database has no file to back up.
Each subcommand:
- Backs up a SQLite store to
<db>.before-reencrypt-<timestamp> - Re-encrypts every row inside a single SQL transaction
- Verifies that every row decrypts under the new key
- Persists the new key to the module's key file in
<secrets-dir>(see the table above)
If any step fails the operation aborts. The transaction guarantees the database is left unchanged if step 2 errors; if step 3 fails, restore from the backup before restarting the server.
Common flags:
| Flag | Description | Default |
|---|---|---|
--db | Path to the module's SQLite file | The module's store, found by --config / --data-dir |
--dsn | Postgres connection string of the module's database (<store>_db), for a service whose configuration the CLI does not read (Enterprise). The new key is printed, not written | - |
--old-key | Current encryption key (16/24/32 bytes ASCII or base64) | Read from the module's key file. If the file is missing, connectors, uns and maestro fall back to the legacy built-in key; auth, oauth2, email and fleet_client stop and ask for --old-key |
--new-key | New encryption key (16/24/32 bytes ASCII or base64) | Freshly generated random AES-256 |
--secrets-dir | Directory holding the persisted secrets files | <storage.dataDir>/secrets |
--key-file | Override the secrets file name | The module's key file (see the table above) |
Re-encrypt Connectors
Re-wrap encrypted_secrets in connections and connections_history.
admin-cli reencrypt connectors [flags]
Examples:
Generate a fresh random AES-256 key, rewrap, and persist:
admin-cli --data-dir ~/maestrohub/data reencrypt connectors
Rotate to an explicit key (e.g. supplied by your KMS):
admin-cli --config /etc/maestrohub/config.yaml reencrypt connectors \
--new-key "$(cat /path/to/new-key.b64)"
Re-encrypt UNS
Re-wrap encryptedSecrets in uns_settings and uns_settings_history.
admin-cli reencrypt uns [flags]
Example:
admin-cli --data-dir ~/maestrohub/data reencrypt uns
Re-encrypt Auth, OAuth2, Email, Fleet Client and Maestro
The other subcommands work the same way and take the same flags:
admin-cli --data-dir ~/maestrohub/data reencrypt auth
admin-cli --data-dir ~/maestrohub/data reencrypt oauth2
admin-cli --data-dir ~/maestrohub/data reencrypt email
admin-cli --data-dir ~/maestrohub/data reencrypt fleet_client
admin-cli --data-dir ~/maestrohub/data reencrypt maestro
Recovery
If verification (step 3) fails, the database has been re-encrypted but cannot be read under the new key. Restore from the backup before restarting the server:
mv ~/maestrohub/data/connectors.db.before-reencrypt-<timestamp> \
~/maestrohub/data/connectors.db
After a successful re-encryption, restart MaestroHub. It picks up the new key from the secrets file on next boot, so no further configuration needed.
If you set a module's key yourself (modules.<module>.config.encryptionKey in config.yaml, modules.fleetClient.encryptionKey for the Fleet client, or the matching MAESTROHUB_* variable), MaestroHub uses that value and ignores the key file. Pass that value as --old-key, and after the rotation put the new key in the same place before you restart.
UNS Commands
Cold-store Statistics
Summarize the UNS historian's Parquet cold store: partition count, total size, newest and oldest hour bucket, a per-workspace breakdown and the number of quarantined files. It only reads file names and sizes, so it is safe to run while MaestroHub is running.
admin-cli uns cold-stats [--cold-root <dir>]
| Flag | Description | Default |
|---|---|---|
--cold-root | The cold-store root directory | modules.uns.defaults.historian.pebble.coldRoot, else <storage.dataDir>/unsdata-cold, found by --config / --data-dir |
Troubleshooting
"no auth store at …"
The CLI looked where the storage rule keeps the auth store and found nothing. Name the installation (--config <its config.yaml> or --data-dir <its storage.dataDir>) or the store itself:
admin-cli --data-dir ~/maestrohub/data db test
admin-cli -d ~/maestrohub/data/auth.db db test
"the auth store is in more than one place"
A store is both where this version keeps it and where an earlier release kept it. Run context-platform upgrade check: it says which one is current. Move the other out of the way.
"Failed to connect to database"
- Verify the database file exists (for SQLite)
- Check that the connection URL is correct (for PostgreSQL)
- Ensure the database server is running and accessible
- Verify network connectivity and firewall rules
"No user found with email"
The specified email address does not exist in the database. Use user list to verify the correct email address.