Skip to main content
Version: 3.0

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:

FlagWhat 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 --config the file you start MaestroHub with.
  • Docker: run the CLI in the container (docker exec --user maestrohub <container> admin-cli …): its working directory is the /data volume, so the default ./data is the image's /data/data. Pass --user maestrohub: the image starts as root to make /data writable and then runs MaestroHub as maestrohub, 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: --config the file whose storage.engine is postgres; the CLI connects to <store>_db on storage.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:

    VariableDescription
    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 / PGDATABASE variables (PGDATABASE defaults to auth_db).

  • the reencrypt commands: --db, --dsn and --secrets-dir (below).

Global Flags​

These flags can be used with any command:

FlagShortDescription
--configThe context engine's config.yaml (see above)
--data-dirThe context engine's storage.dataDir (see above)
--database-dThe auth store's path or URL, for the user and db commands
--verbose-vEnable verbose output
--force-fSkip confirmation prompts
--versionDisplay version information
--help-hDisplay help information

Commands​

User Commands​

List Users​

Display all users in the system.

admin-cli user list [--limit <number>]

Options:

FlagDescriptionDefault
--limitMaximum number of users to display20

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:

FlagShortDescriptionDefault
--email-eUser's email address (required)-
--password-pNew passwordTempPassword2024!

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
warning

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).

SubcommandWhat it re-encryptsKey file
reencrypt connectorsConnection secrets, in connections and connections_historyconnectors_encryption_key
reencrypt unsUNS settings secrets, in uns_settings and uns_settings_historyuns_encryption_key
reencrypt authIdentity-provider secrets (OIDC client secrets, LDAP bind passwords) and the key that signs personal access tokensauth_encryption_key
reencrypt oauth2The OAuth2 server's token-signing private keysoauth2_encryption_key
reencrypt emailThe SMTP passwords of the email configurationemail_encryption_key
reencrypt fleet_clientThe context engine's API key to its Fleet Managerfleet_client_encryption_key
reencrypt maestroMaestro AI provider-account API keys (the Maestro agent is in Beta, on request)chat_encryption_key
Stop the server first

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.

Which store

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:

  1. Backs up a SQLite store to <db>.before-reencrypt-<timestamp>
  2. Re-encrypts every row inside a single SQL transaction
  3. Verifies that every row decrypts under the new key
  4. 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:

FlagDescriptionDefault
--dbPath to the module's SQLite fileThe module's store, found by --config / --data-dir
--dsnPostgres 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-keyCurrent 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-keyNew encryption key (16/24/32 bytes ASCII or base64)Freshly generated random AES-256
--secrets-dirDirectory holding the persisted secrets files<storage.dataDir>/secrets
--key-fileOverride the secrets file nameThe 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.

A key set in the configuration wins over the file

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>]
FlagDescriptionDefault
--cold-rootThe cold-store root directorymodules.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.