Looking to hire Laravel developers? Try LaraJobs

laravel-source-guard maintained by amirrajabzadeh

Description
رمزگذاری امن سورس‌کد PHP در پروژه‌های Laravel/Lumen با مدیریت کلید مبتنی بر Master Key + HKDF
Last update
2026/07/25 05:06 (dev-main)
License
Downloads
1

Comments
comments powered by Disqus

Laravel Source Guard

Tests Latest Stable Version License

Securely encrypt your Laravel/Lumen PHP source code using phpBolt, with a Master Key + HKDF key-management layer that keeps per-file decryption keys out of the shipped files themselves.

Requires PHP 8.1+, Laravel/Lumen 10+, and the phpBolt PHP extension.

Why a new package?

This project started as an architectural rewrite of Laravel-Source-Encrypter by Siavash Bamshadnia. Credit to the original author for the concept. Laravel Source Guard is a from-scratch redesign focused on:

  • Key security — the original package embedded each file's plaintext decryption key directly inside that same file. Laravel Source Guard derives per-file keys at runtime from a Master Key that never ships with your code (see Security model).
  • Driver-based architecture (Strategy pattern) — encryption backends are pluggable via an EncryptionDriver interface, so other encoders can be added later without touching the core.
  • Testability — the core logic has zero dependency on the bolt extension being installed; a fake driver is used in the test suite.
  • Correctness fixes — proper extension detection, safe recursive directory traversal, cross-platform path handling, and destination rollback on failure.

Security model

                     ┌────────────────────────┐
                     │      Master Key         │  ← lives only in production
                     │ (SOURCE_GUARD_MASTER_KEY)│    server's environment, never
                     └───────────┬─────────────┘    committed to Git
                                 │  HKDF (RFC 5869)
                                 ▼
                     per-file derived key  ──────►  used to bolt_encrypt() the file
                                 │
                                 ▼
              encrypted file only contains a *file identifier*,
              not the derived key. At runtime, KeyResolver re-derives
              the same key from the environment's Master Key.

What this protects against: someone who only has a copy of your encrypted files (without access to your production server's environment) cannot derive the decryption keys.

What this does not change: phpBolt (like any similar PHP encoder) must reconstruct the key at the moment the file executes, so the logic to obtain a key is necessarily present in readable PHP at the top of every encrypted file — this is an inherent constraint of this class of tool, not something this package can eliminate. What Laravel Source Guard changes is that this logic requires the Master Key from the serving environment, not a value shipped inside the file.

Because of this, amirrajabzadeh/laravel-source-guard must be installed as a production dependency (composer require, not --dev) — the KeyResolver class is needed at runtime, not just at build time.

Installation

composer require amirrajabzadeh/laravel-source-guard

The service provider is auto-discovered. For Lumen, register it manually in bootstrap/app.php:

$app->register(\AmirRajabzadeh\LaravelSourceGuard\LaravelSourceGuardServiceProvider::class);

Publish the config file (optional):

php artisan vendor:publish --provider="AmirRajabzadeh\LaravelSourceGuard\LaravelSourceGuardServiceProvider" --tag=source-guard-config

You also need the phpBolt extension installed on any machine where you run source-guard:encrypt, and on your production server (for decryption).

Usage

1. Generate a Master Key

php artisan source-guard:generate-key

Copy the printed SOURCE_GUARD_MASTER_KEY=... line into your production server's .env file (never commit it). This same value must be present wherever the encrypted files will actually run.

2. Encrypt your source

php artisan source-guard:encrypt

By default this encrypts app, database, and routes into an encrypted/ directory, using the Master Key from your local .env (used only to derive keys during the build — the derived keys are never written to disk).

Options

Option Description Example
--source Comma-separated paths to encrypt --source=app,routes
--destination Destination directory --destination=dist
--exclude Comma-separated glob patterns to skip --exclude=tests/*,*.blade.php
--force Overwrite destination without prompting --force
--dry-run Preview the operation without writing any files --dry-run

What gets encrypted

Only .php files are encrypted. .blade.php files are always copied unchanged (Blade's own compiler needs to read their raw syntax, so encrypting them would break view rendering). Any other extension is copied as-is with a one-time warning.

.env files are never touched by this package and should never be deployed as part of your source tree in the first place — see Laravel's own deployment/secrets-management guidance instead.

Configuration

config/source-guard.php:

return [
    'source'      => ['app', 'database', 'routes'],
    'destination' => 'encrypted',
    'exclude'     => [],
    'master_key'  => env('SOURCE_GUARD_MASTER_KEY'),
    'driver'      => 'bolt',
];

Extending with a new encryption driver

Implement AmirRajabzadeh\LaravelSourceGuard\Contracts\EncryptionDriver and bind it in your own service provider:

$this->app->bind(\AmirRajabzadeh\LaravelSourceGuard\Contracts\EncryptionDriver::class, MyCustomDriver::class);

License / Domain Binding (optional)

On top of the Master Key protection, you can restrict encrypted files to only run on a specific set of domains:

# .env (on the machine running source-guard:encrypt, and on production)
SOURCE_GUARD_LICENSE_BINDING_ENABLED=true
SOURCE_GUARD_ALLOWED_DOMAINS=example.com,*.example.com

When enabled, every encrypted file gets a small runtime check injected before decryption that compares the current server's domain (HTTP_HOST / SERVER_NAME, or SOURCE_GUARD_CURRENT_DOMAIN for CLI/queue contexts) against your allowed_domains list, and refuses to run on anything else — see AmirRajabzadeh\LaravelSourceGuard\Runtime\LicenseBindingGuard.

Honest scope of this feature: the check itself is plain, readable PHP (like the rest of the runtime stub — this is an inherent constraint of any PHP encoder that decrypts at request time, not something specific to this package). It is a policy/licensing control, not an additional cryptographic layer by itself. Its real value shows up in combination with the Master Key: if your production .env (Master Key included) ever leaks and someone copies your codebase to an unauthorized server, this guard still stops it from running there.

If you enable license_binding but leave allowed_domains empty, source-guard:encrypt will refuse to run — an empty allow-list would otherwise mean nothing is allowed to execute anywhere, which is almost certainly not what you want.

Testing

composer install
composer test        # runs Pest

# Static analysis tools (phpstan/larastan) are intentionally NOT part of
# the main require-dev, to avoid version conflicts with the Laravel 11/12
# test matrix (larastan currently caps the Illuminate version it supports).
# Install them once with:
composer prepare-analysis
composer analyse

The test suite uses a fake, non-cryptographic driver so it can run without the commercial bolt extension installed.

Note on Composer's advisory audit: this package's composer.json sets config.policy.advisories.block to false. Recent Composer versions block installing any package version affected by a disclosed security advisory by default — including, at times, the current latest release of actively maintained packages such as laravel/framework. Disabling the block keeps composer install/update usable for testing across the supported Laravel matrix; advisories are still reported (not silenced) via composer audit, which you should run separately as part of your own release process.

License

MIT. See LICENSE.