Encrypted backups

The SDK can back up your database or any file/folder to Quiet Guard's zero-knowledge vault. Everything is encrypted on your server before upload, with a key only your team can unlock. The server stores an opaque blob and never sees your data or your key.

Prerequisites

  • Encryption must be enabled for your team in the Quiet Guard dashboard (this generates the team key pair and is protected by a team passphrase). The backup vault is a paid feature subject to a storage quota. See the server documentation.
  • PHP built with libsodium (ext-sodium, bundled by default since PHP 7.2).
  • For non-SQLite databases, the matching dump binary on the host: mysqldump (MySQL / MariaDB) or pg_dump (PostgreSQL). SQLite databases are copied directly.

Creating a backup

bash
# Back up the default database connection
php artisan monitor:backup --database

# Back up a file or directory
php artisan monitor:backup --path=/var/www/storage/app

# Add a human-readable label
php artisan monitor:backup --database --name="nightly"

Options

OptionDescription
--databaseBack up the default database connection (config('database.default')).
--path=Back up a single file or a whole directory.
--name=Optional label stored alongside the backup. Printable ASCII, no slashes, up to 255 characters: the label becomes the filename the download is offered under, and a path separator is not something an HTTP header can carry. The server answers 422 and names the field when it refuses one.

You must pass either --database or --path. When MONITOR_ENABLED=false, the command does nothing.

How the archive is built

  • --database: SQLite connections are copied as-is; MySQL/MariaDB are dumped with mysqldump, PostgreSQL with pg_dump. The password is passed through the environment (MYSQL_PWD / PGPASSWORD), never on the command line. The dump runs with a 600-second timeout. The backup is recorded with type database.
  • --path: a directory is packed into a tar archive (a single file is added to a tar), recorded with type files.

Restoring a backup

bash
php artisan monitor:restore <id>

# Choose where the decrypted output is written
php artisan monitor:restore <id> --output=/tmp/restore.sql

# Provide the passphrase non-interactively (otherwise you are prompted)
php artisan monitor:restore <id> --passphrase="…"

Options

Argument / optionDescription
id (argument)The backup id returned when the backup was uploaded.
--output=Where to write the decrypted result. Defaults to restored-<id>.out in the app base path.
--passphrase=The team passphrase. Prompted securely (hidden input) if omitted.

The decrypted output is the raw archive: a SQL dump (or SQLite file) for --database backups, or a tar archive for --path backups. Because the default output is restored-<id>.out, pass --output with an appropriate extension when you want to use it directly, e.g. --output=restore.sql or --output=files.tar.

How the encryption works

Backups use hybrid streaming encryption, shared with every other Quiet Guard client through the quiet-guard/monitor-php core:

  1. A random symmetric key encrypts the archive with libsodium's secretstream (chunked XChaCha20-Poly1305 AEAD, 64 KiB chunks), so large dumps are streamed, never held whole in memory.
  2. That symmetric key is sealed to your team's X25519 public key (crypto_box_seal). The sealed key is prepended to the blob.
  3. The encrypted blob is uploaded to /api/v1/backups. The server stores it opaquely, alongside metadata (type, name, size), and enforces your storage quota.

To restore, the SDK fetches your key material from /api/v1/encryption-key (public key, the passphrase-wrapped private key, and the KDF salt), then unwraps the private key locally from your passphrase: an Argon2id key-derivation (MODERATE limits) reproduces the key-encryption key and opens a libsodium secretbox, exactly mirroring the server's own wrapping. The unwrapped key opens the sealed symmetric key, which decrypts the stream.

This is zero-knowledge: the passphrase and the unwrapped private key never leave your server, and the operator is never able to read your backups. The trade-off is that a lost passphrase means the backup cannot be recovered, there is no reset.

Scheduling

Schedule nightly database backups from your application's scheduler:

php
use Illuminate\Support\Facades\Schedule;

Schedule::command('monitor:backup --database --name=nightly')->dailyAt('02:00');

Tying it to the vault

The vault, GB quota and the encrypted-blob UI live on the server side. See the server documentation for browsing backups, downloading the raw encrypted blob, and managing storage.

You are reading the Laravel SDK v1.0 documentation.