nyoncode/laravel-backup-manager

nyoncode/laravel-backup-manager

Powerful and extensible backup manager for Laravel applications: databases, files, encryption, integrity manifests and multi-destination storage.

0
Packagist stažení
0
Verzí
1.1.1
Aktuální verze
Závislosti
php ^8.3 ext-json * ext-openssl * illuminate/bus ^12.0|^13.0 illuminate/console ^12.0|^13.0 illuminate/contracts ^12.0|^13.0 illuminate/database ^12.0|^13.0 illuminate/filesystem ^12.0|^13.0 illuminate/queue ^12.0|^13.0 illuminate/support ^12.0|^13.0 nyoncode/laravel-package-toolkit ^2.1.1 symfony/finder ^7.0 symfony/process ^7.0

Security & the manifest

Backup Manager provides four layers of protection: encryption, checksums, signing and the manifest.

Encryption

The final archive can be encrypted with AES-256 using ext-openssl:

1'encryption' => [
2 'algorithm' => 'aes-256-gcm', // none | aes-256-cbc | aes-256-gcm
3 'key' => env('BACKUP_ENCRYPTION_KEY'),
4],

Choosing a mode

Mode Authenticated Streaming Use when
aes-256-cbc no yes (flat memory) very large archives
aes-256-gcm yes (tamper-evident) buffered in memory archives that fit comfortably in memory

GCM detects tampering on decrypt (an altered archive fails to restore). CBC streams block-by-block so arbitrarily large archives encrypt with flat memory.

Memory: GCM buffers the whole archive in memory. To avoid exhausting memory on very large backups, GCM refuses archives larger than encryption.gcm_max_megabytes (default 1024) with a clear error — use aes-256-cbc for large backups, or raise the limit.

The key

The key must be 32 bytes. A base64: prefix is decoded automatically, so you can reuse the Laravel convention:

1php -r "echo 'base64:'.base64_encode(random_bytes(32)).PHP_EOL;"
1BACKUP_ENCRYPTION=aes-256-gcm
2BACKUP_ENCRYPTION_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=

⚠️ Store the key outside the backup. Without it, an encrypted backup cannot be restored. The key is never written to the manifest or logs.

Checksums

Every backup records a checksum (SHA-256 by default; SHA-512 optionally) of:

  • the whole archive — verified before every restore, and by backup:verify;
  • each individual file — recorded in the manifest for per-file verification.
1'integrity' => ['checksum' => 'sha256'], // sha256 | sha512

Comparison is constant-time to avoid timing side-channels.

Signing

Pro feature. HMAC manifest signing requires Backup Manager Pro. The free core keeps the Signer contract but binds no implementation: with signing enabled but Pro absent a backup fails closed, so it is never written unsigned while you believe it is signed.

An optional keyed HMAC signature authenticates the manifest itself — proving the backup was produced by a holder of the signing key and has not been altered:

1'integrity' => [
2 'signing' => [
3 'enabled' => true,
4 'key' => env('BACKUP_SIGNING_KEY'), // defaults to the encryption key
5 ],
6],

backup:verify reports both the archive checksum and the signature status.

The manifest

Every backup ships a *.manifest.json sidecar — a self-describing record that makes the backup verifiable independently of this package. It contains:

  • schema version, profile name, backup type, creation timestamp;
  • the environment: app name & version, Laravel version, PHP version, environment name, operating system;
  • the drivers used: compression, encryption, checksum algorithms;
  • the databases dumped (connection, driver, database name, archived path);
  • the archive size and checksum;
  • every file: archive path, size, checksum, symlink info;
  • an optional signature.

Because it is a sidecar, you can read it and verify the archive without decrypting — it is plain JSON you can open in any editor.

Verifying a backup

1php artisan backup:verify # newest backup
2php artisan backup:verify my-backup.tar.gz.enc

This downloads the archive, recomputes its checksum against the manifest and, if signed, verifies the signature — the lightweight restorability test. Restores also perform this check automatically (disable with --no-verify).