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) orpg_dump(PostgreSQL). SQLite databases are copied directly.
Creating a backup
Options
| Option | Description |
|---|---|
--database | Back 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 withmysqldump, PostgreSQL withpg_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 typedatabase.--path: a directory is packed into a tar archive (a single file is added to a tar), recorded with typefiles.
Restoring a backup
Options
| Argument / option | Description |
|---|---|
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:
- 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.
- That symmetric key is sealed to your team's X25519 public key (
crypto_box_seal). The sealed key is prepended to the blob. - 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:
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.