Admin Scripts
How admin scripts are run#
Operational verbs that live outside the web UI ship as plain Python scripts
under scripts/ inside the backend container. They read the same
environment as the running service (ABRQ_DATABASE_URL, ABRQ_MASTER_KEY,
…), so run them inside the backend container of the deployment they
should act on.
On Docker Compose:
docker compose exec backend uv run python scripts/<SCRIPT>.py --help
On Kubernetes, execute the same python scripts/<SCRIPT>.py command inside a
running api pod (for example with kubectl exec).
Note. There is no
abrqCLI wrapper — the invocations below are the real interface. There is also no healthcheck script: to check platform health, callGET /health(see Monitoring).
backup_metadata.py — metadata backup and restore#
Dumps or restores the framework database's configuration + progress state as a single always-encrypted file.
docker compose exec backend uv run python scripts/backup_metadata.py \
dump --out /var/abrq-dip/backup-<DATE>.json.enc
docker compose exec backend uv run python scripts/backup_metadata.py \
restore --in /tmp/restore.json.enc --force
dump --out <PATH>— writes the Fernet-encrypted envelope (name it*.json.enc).restore --in <PATH>— refuses non-empty target tables by default;--forceTRUNCATEs first (destructive);--allow-schema-mismatchoverrides the schema-version check (rarely safe).
Full coverage — what's included, scheduled auto-backup, and the restore runbook — is in Backup and restore.
rotate_master_key.py — re-wrap stored secrets#
Re-encrypts every row of the encrypted secrets store under a new master key, with no downtime and no window where rows are unreadable.
-
Configure the key list with the new key first:
export ABRQ_MASTER_KEY=<NEW_KEY>,<OLD_KEY> -
Run the script — it walks the secrets table, decrypts each row with whichever configured key works, and writes it back under the new key:
docker compose exec backend uv run python scripts/rotate_master_key.py -
Once it reports success, drop
<OLD_KEY>from the environment on the next deploy.
The script is idempotent — a second run is a no-op — and safe to interrupt: with both keys still configured, half-rotated rows remain readable; just re-run to finish. It exits non-zero if any row failed to re-wrap (those rows are left untouched — investigate before retiring the old key).
Follow the full runbook, including verification steps and when to rotate, in Secrets and encryption.
verify_audit_chain.py — audit-log integrity check#
Walks the audit log's hash chain from the shell — the same verification the
daily scheduled task and the admin API endpoint
(POST /api/v1/admin/audit/verify-chain) perform, made available for
air-gapped operators without a browser:
docker compose exec backend uv run python scripts/verify_audit_chain.py
Exit codes:
| Code | Meaning |
|---|---|
0 |
Chain intact (rows checked and pre-chain rows skipped are logged) |
1 |
Chain broken — a chained audit row was modified or deleted. Treat as a security incident: preserve the audit_log table before touching anything |
2 |
Verification could not run (database unreachable, bad config) — integrity is unproven, not disproven; never read this as either verdict |
The script is read-only — it writes nothing, not even an audit row. See Audit for how the chain works.