worksome / foggy-laravel
Adds Foggy support in Laravel
Requires
- php: ^8.4
- doctrine/dbal: ^3.5.1 || ^4.0
- illuminate/console: ^12.0 || ^13.0
- illuminate/database: ^12.0 || ^13.0
- illuminate/filesystem: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
- thecodingmachine/safe: ^3.0
- worksome/foggy: ^0.7.1
Requires (Dev)
- aws/aws-sdk-php: ^3.401
- league/flysystem-aws-s3-v3: ^3.35
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^10.1 || ^11.0
- pestphp/pest: ^4.4
- pestphp/pest-plugin-laravel: ^4.1
- worksome/coding-style: ^3.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
This package is a Laravel wrapper for Foggy.
Configuration of the plugin can be found at Foggy's docs.
Install
Via Composer
composer require worksome/foggy-laravel
Usage
This package adds a new artisan command for running Foggy. Simply type:
php artisan db:dump
It will by default assume that the Foggy config file, will be in foggy.json in the root of the project.
A configuration file can be supplied by using --config argument.
The artisan command by default will make the database dump to stdout. To pass the output to a file, use the --output (-o) option.
php artisan db:dump --output scrubbed-dump.sql
Foggy also supports specifying a custom database connection:
php artisan db:dump --connection mysql
Uploading a dump to a filesystem disk
db:dump-to-disk streams the scrubbed dump through gzip and onto any configured
filesystem disk. Nothing is written to local disk on the way, so it works in a
container with no spare space — which starts to matter once a dump is tens of
gigabytes.
Its size is not known up front, so on S3 a dump of 5 MB or more goes up as a
multipart upload and a smaller one as a single PutObject.
php artisan db:dump-to-disk --disk=dumps --connection=replica
It writes two objects:
dumps/dump-YYYY-MM-DD-HHMMSS-xxxxxx.sql.gz, the dump itselfdumps/latest, naming the most recent complete dump
Read the pointer rather than guessing a filename. Keys carry a timestamp and a
random suffix, so a re-run never reuses the key of a published dump even when it
starts in the same second, and latest is only written after the dump has
finished and passed the scan below — so a truncated or rejected dump is never the
one consumers pull.
Options: --disk, --prefix (default dumps), --name (default dump),
plus --connection and --config, which are passed through to db:dump.
Checking that the rules actually worked
A Foggy config can only protect the columns it knows about. A new column on a
table that is already withData: true is dumped raw, and neither the config nor
the schema reveals that.
So the upload scans its own output, and fails without writing latest if it
finds anything. A rejected dump fails the final read of the stream, so a disk
that only stores an object once its stream ends cleanly — S3, for one — never
stores it, and a write-only credential needs no delete permission to stay safe.
One caveat: a dump large enough for a multipart upload leaves its uploaded parts
behind, since the AWS SDK does not abort the upload — give the bucket an
AbortIncompleteMultipartUpload lifecycle rule so they expire.
The defaults look for email addresses, IBANs and Danish CPR
numbers — deliberately a short, high-confidence list, because a scan that cries
wolf gets switched off. Replace them per project:
// config/foggy.php return [ 'scan_patterns' => [ 'email address' => '/[\w.%+-]+@(?!example\.(?:org|com|net)\b)[\w-]+\.[a-z]{2,}/i', 'employee number' => '/\bEMP-\d{5}\b/', ], ];
The patterns are replaced, not merged, so a default that is noisy against your data can simply be dropped.
One constraint: the scan reads the dump in chunks and carries 256 bytes between them, so a pattern that can match more than that could miss an occurrence straddling a chunk boundary. The defaults are well inside it (an email address caps out at 254 characters). If you add something longer, widen the window:
// config/foggy.php return [ 'scan_overlap_bytes' => 1024, ];
Patterns are validated when the scanner is constructed — one that will not
compile raises InvalidArgumentException rather than silently matching nothing.
A pattern that compiles but then fails mid-dump, such as a /u pattern meeting
the non-UTF-8 bytes of a BLOB column, fails the run too: an unfinished scan is
not evidence that the dump is clean.