PHPackages                             filastudio/laravel-vigil - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. filastudio/laravel-vigil

ActiveLibrary[Security](/categories/security)

filastudio/laravel-vigil
========================

A security audit package for Laravel applications with Filament v5 integration.

v1.0.0(4mo ago)1254MITPHPPHP ^8.2CI failing

Since Feb 22Pushed 4mo agoCompare

[ Source](https://github.com/filastudio/laravel-vigil)[ Packagist](https://packagist.org/packages/filastudio/laravel-vigil)[ RSS](/packages/filastudio-laravel-vigil/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (10)Versions (2)Used By (0)

Laravel Vigil
=============

[](#laravel-vigil)

[![Laravel Vigil](https://private-user-images.githubusercontent.com/2721390/553208340-bf5d25ca-7fd8-4651-9cd8-cc9de0964553.jpg?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODI2NzIxMTIsIm5iZiI6MTc4MjY3MTgxMiwicGF0aCI6Ii8yNzIxMzkwLzU1MzIwODM0MC1iZjVkMjVjYS03ZmQ4LTQ2NTEtOWNkOC1jYzlkZTA5NjQ1NTMuanBnP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDYyOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjA2MjhUMTgzNjUyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZGEyZTQyNDZjZDhhY2U2MWFhOTEyYTQ2ODhkNjFlNTU4ZTg0ZGM1Mzg5MTM2OWYyOWU3OGM5MTQ1YzJiZGJhOCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmcmVzcG9uc2UtY29udGVudC10eXBlPWltYWdlJTJGanBlZyJ9.OYVlj5otTqwrV_fM7pHdi8C_Gx9zlyZaeP9DZcGue5k)](https://private-user-images.githubusercontent.com/2721390/553208340-bf5d25ca-7fd8-4651-9cd8-cc9de0964553.jpg?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODI2NzIxMTIsIm5iZiI6MTc4MjY3MTgxMiwicGF0aCI6Ii8yNzIxMzkwLzU1MzIwODM0MC1iZjVkMjVjYS03ZmQ4LTQ2NTEtOWNkOC1jYzlkZTA5NjQ1NTMuanBnP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDYyOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjA2MjhUMTgzNjUyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZGEyZTQyNDZjZDhhY2U2MWFhOTEyYTQ2ODhkNjFlNTU4ZTg0ZGM1Mzg5MTM2OWYyOWU3OGM5MTQ1YzJiZGJhOCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmcmVzcG9uc2UtY29udGVudC10eXBlPWltYWdlJTJGanBlZyJ9.OYVlj5otTqwrV_fM7pHdi8C_Gx9zlyZaeP9DZcGue5k)

[![Latest Version on Packagist](https://camo.githubusercontent.com/b15e07bb382fab35205792ec0dd088d9dba770a3b7951c594597a3242fed7af5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f66696c6173747564696f2f6c61726176656c2d766967696c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/filastudio/laravel-vigil)[![GitHub Tests Action Status](https://camo.githubusercontent.com/bb22140cc554dc58a94fc835ff1a4c51a5be61a2686b68bb04841a344ff75752/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f66696c6173747564696f2f6c61726176656c2d766967696c2f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/filastudio/laravel-vigil/actions?query=workflow%3Atests+branch%3Amain)[![PHP Version](https://camo.githubusercontent.com/3f8cc2114da2d3380f25bc1c0e68a9ab00794b5048077553d666a6d49479afc2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f66696c6173747564696f2f6c61726176656c2d766967696c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/filastudio/laravel-vigil)[![Laravel Version](https://camo.githubusercontent.com/614144e3d2c906fc5c0df998af509529dd74ee10182e59a70c6c70e185f5a040/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d31312e7825323025374325323031322e782d7265642e7376673f7374796c653d666c61742d737175617265)](https://laravel.com)[![License](https://camo.githubusercontent.com/3facf2cab0a9b334707168f20ecc292220480ea483ae69d97d59081890e128dc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f66696c6173747564696f2f6c61726176656c2d766967696c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/filastudio/laravel-vigil)

Security audit tool for Laravel. Scans your application's filesystem, PHP configuration, HTTP headers, and Composer dependencies for common vulnerabilities and misconfigurations. Ships with 15 checks out of the box, a scoring system, and an optional Filament v5 dashboard.

Features
--------

[](#features)

- **15 built-in checks** grouped into 5 categories (filesystem, configuration, HTTP headers, dependencies, extended)
- **Filesystem scanning** for malicious JS, dangerous uploads, wrong permissions, and exposed sensitive files
- **Configuration audits** covering PHP.ini, `.env`, session, and CORS settings
- **HTTP header validation** (HSTS, CSP, X-Frame-Options, etc.)
- **Composer audit integration** to flag vulnerable packages
- **Hardcoded secret detection** with smart `env()` filtering to reduce false positives
- **Security score** from 0 to 100 based on check results
- **File integrity monitoring** via SHA-256 baseline comparison
- **Filament v5 dashboard** (optional) with scan history, score widgets, and one-click scanning
- **JSON and table output**, CI/CD-friendly exit codes
- **Extensible** with custom checks via a simple interface
- **PHP 8.2 enums** for status, severity, and category values

Why this package
----------------

[](#why-this-package)

We kept running into the same issues across projects: `.env` files accessible via HTTP, debug mode left on in production, API keys committed to repos, malicious files sneaking into upload directories. Vigil automates the checks we were doing manually.

A few things we focused on:

- **Low noise.** Each check is tuned to avoid false positives. The secret scanner, for example, understands `env()` calls and won't flag them.
- **Useful output.** Failed checks include the exact file, line number, and a concrete fix suggestion.
- **Reasonable performance.** File scanning respects size limits so it won't choke on large codebases.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11.x or 12.x
- Filament 5.x (optional, for the dashboard)

Installation
------------

[](#installation)

```
composer require filastudio/laravel-vigil
```

The service provider registers automatically.

Publish the config:

```
php artisan vendor:publish --tag=vigil-config
```

If you want scan history stored in the database:

```
php artisan vendor:publish --tag=vigil-migrations
php artisan migrate
```

This creates `vigil_scans` and `vigil_check_results` tables. Old records are cleaned up automatically based on the retention setting in config.

Run your first scan:

```
php artisan vigil:audit
```

Configuration
-------------

[](#configuration)

The configuration file `config/vigil.php` allows you to enable/disable individual checks and customize behavior:

```
return [
    // Enable or disable individual checks
    'checks' => [
        'fs.public_folder'        => true,
        'fs.malicious_js'         => true,
        'fs.storage_dangerous'    => true,
        'fs.permissions'          => true,
        'fs.sensitive_exposure'   => true,
        'cfg.php_ini'             => true,
        'cfg.env'                 => true,
        'cfg.session'             => true,
        'cfg.cors'                => true,
        'http.headers'            => true,
        'dep.composer_audit'      => true,
        'ext.hardcoded_secrets'   => true,
        'ext.debug_routes'        => true,
        'ext.telescope_debugbar'  => true,
        'ext.file_integrity'      => false, // Requires baseline
    ],

    // Allowed file extensions in public directory
    'public_allowed_extensions' => [
        'css', 'js', 'jpg', 'jpeg', 'png', 'gif', 'svg', 'webp',
        'ico', 'woff', 'woff2', 'ttf', 'eot', 'pdf', 'map', 'txt',
    ],

    // Dangerous file extensions in storage
    'storage_dangerous_extensions' => [
        'php', 'phtml', 'phar', 'php3', 'php4', 'php5', 'php7',
        'exe', 'bat', 'cmd', 'sh', 'bash', 'bin', 'js', 'vbs', 'ps1',
    ],

    // Store scan results in database
    'store_results' => true,

    // Retention period for scan results (days)
    'results_retention_days' => 90,

    // Notification settings (future feature)
    'notifications' => [
        'enabled'            => false,
        'channels'           => ['mail'],
        'notify_on_severity' => ['critical', 'high'],
        'mail_to'            => env('VIGIL_MAIL_TO', null),
    ],
];
```

Usage
-----

[](#usage)

### Artisan Commands

[](#artisan-commands)

#### `vigil:audit`

[](#vigilaudit)

Runs all enabled checks and prints results as a table:

```
php artisan vigil:audit
```

Options:

- `--category=filesystem,configuration` — filter by category
- `--check=fs.public_folder,cfg.env` — run specific checks only
- `--fail-on=critical,high` — exit with code 1 on matching severity (default: `critical`)
- `--format=json` — JSON output instead of table
- `--output=/path/to/file.json` — write JSON to file
- `--detailed` — show full messages, file paths, line numbers, and fix suggestions

Examples:

```
# Only filesystem checks
php artisan vigil:audit --category=filesystem

# Specific checks with details
php artisan vigil:audit --check=fs.public_folder,cfg.env --detailed

# JSON report
php artisan vigil:audit --format=json --output=storage/security-report.json

# CI/CD: fail on critical or high
php artisan vigil:audit --fail-on=critical,high
```

#### `vigil:baseline`

[](#vigilbaseline)

Generates SHA-256 hashes of files in `public/` and `storage/app/public/` for integrity monitoring:

```
php artisan vigil:baseline
```

Saves to `storage/app/vigil_baseline.json`. Once a baseline exists, enable the `ext.file_integrity` check in config to compare against it on subsequent scans.

#### `vigil:list`

[](#vigillist)

Shows all 15 checks with their category, severity, and enabled/disabled status:

```
php artisan vigil:list
```

### Detailed Output

[](#detailed-output)

The `--detailed` flag adds full context to each check result: untruncated messages, exact file paths with line numbers, and specific recommendations.

```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ✗ FAILED - Hardcoded Secrets Detection                                     │
│ ID: ext.hardcoded_secrets | Category: extended | Severity: CRITICAL        │
├─────────────────────────────────────────────────────────────────────────────┤
│ Message: Found 3 potential hardcoded secrets in your codebase              │
│                                                                             │
│ Details:                                                                    │
│   • app/Services/PaymentService.php:42                                     │
│     $apiKey = 'sk_live_abc123def456';                                      │
│                                                                             │
│   • config/services.php:18                                                 │
│     'secret' => 'hardcoded_secret_key',                                    │
│                                                                             │
│ Recommendation:                                                             │
│   Move all secrets to .env file and use env() helper:                      │
│   $apiKey = env('PAYMENT_API_KEY');                                        │
└─────────────────────────────────────────────────────────────────────────────┘

```

Useful for investigating failures, generating compliance reports, or just understanding what exactly triggered a check.

### Programmatic Usage

[](#programmatic-usage)

You can also run scans from code:

```
use FilaStudio\Vigil\SecurityScanner;

$scanner = app(SecurityScanner::class);

// Run all enabled checks
$results = $scanner->run();

foreach ($results as $checkId => $entry) {
    $check = $entry['check'];   // SecurityCheck instance
    $result = $entry['result'];  // CheckResult instance

    echo "{$check->title()}: {$result->status}\n";

    if ($result->status === 'failed') {
        echo "Message: {$result->message}\n";
        echo "Recommendation: {$result->recommendation}\n";
        print_r($result->details);
    }
}

// Filter by check ID or category
$results = $scanner->run(['fs.public_folder', 'cfg.env']);
$results = $scanner->run(null, ['filesystem', 'configuration']);

// Security score
$passed = count(array_filter($results, fn($e) => $e['result']->status === 'passed'));
$skipped = count(array_filter($results, fn($e) => $e['result']->status === 'skipped'));
$score = $scanner->calculateSecurityScore($passed, count($results), $skipped);

// List all checks (including disabled)
$allChecks = $scanner->getAllChecks();

// Delete old scan records (respects retention config)
$deletedCount = $scanner->cleanupOldScans();
```

Filament Integration
--------------------

[](#filament-integration)

If you use Filament v5, Vigil ships with a dashboard page and widgets.

Register the plugin in your `AdminPanelProvider`:

```
use FilaStudio\Vigil\Filament\VigilPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            VigilPlugin::make()
                ->navigationGroup('Security')
                ->navigationSort(99),
        ]);
}
```

The dashboard includes:

- **Security score widget** — 0-100 score, color-coded by severity
- **Critical issues counter** — number of failed critical checks
- **Recent scans table** — history with scores, timestamps, and issue counts
- **Detailed results** — click into any scan to see per-check results with messages and recommendations
- **Run scan button** — trigger scans from the browser without CLI access

Handy for tracking trends over time, sharing results with the team, or pulling up a quick overview during a meeting.

All Security Checks
-------------------

[](#all-security-checks)

Check IDTitleCategorySeverityDescription`fs.public_folder`Public Folder SecurityfilesystemhighScans for unexpected files in public directory`fs.malicious_js`Malicious JavaScript DetectionfilesystemcriticalDetects obfuscated/malicious JS patterns`fs.storage_dangerous`Dangerous Files in StoragefilesystemcriticalFinds executable files in public storage`fs.permissions`File Permissions CheckfilesystemhighVerifies Unix file permissions (Linux/Mac only)`fs.sensitive_exposure`Sensitive Files ExposurefilesystemcriticalChecks if .env, composer.json, .git are accessible via HTTP`cfg.php_ini`PHP Configuration CheckconfigurationhighValidates PHP ini directives for security`cfg.env`Environment ConfigurationconfigurationcriticalChecks APP\_DEBUG, APP\_KEY, APP\_ENV settings`cfg.session`Session ConfigurationconfigurationmediumValidates session security settings`cfg.cors`CORS ConfigurationconfigurationhighDetects dangerous CORS misconfigurations`http.headers`Security Headers Checkhttp\_headershighEnsures HSTS, CSP, X-Frame-Options, etc. are set`dep.composer_audit`Composer Dependencies AuditdependenciescriticalRuns `composer audit` to find vulnerable packages`ext.hardcoded_secrets`Hardcoded Secrets DetectionextendedcriticalScans for hardcoded passwords, API keys, tokens`ext.debug_routes`Debug Routes DetectionextendedhighFinds debug endpoints (phpinfo, dd, dump) in routes`ext.telescope_debugbar`Telescope &amp; Debugbar CheckextendedhighEnsures debug tools are secured in production`ext.file_integrity`File Integrity CheckextendedcriticalCompares files against baseline to detect tamperingCustom Checks
-------------

[](#custom-checks)

Implement the `SecurityCheck` interface:

```
namespace App\Security\Checks;

use FilaStudio\Vigil\Checks\Contracts\SecurityCheck;
use FilaStudio\Vigil\Checks\Results\CheckResult;
use FilaStudio\Vigil\Enums\Severity;
use FilaStudio\Vigil\Enums\Category;

class DatabaseSSLCheck implements SecurityCheck
{
    public function id(): string { return 'custom.database_ssl'; }
    public function title(): string { return 'Database SSL Connection Check'; }
    public function description(): string { return 'Ensures database connections use SSL in production'; }
    public function category(): string { return Category::Configuration->value; }
    public function severity(): string { return Severity::High->value; }

    public function run(): CheckResult
    {
        if (app()->environment('local')) {
            return CheckResult::skipped('Not applicable in local environment');
        }

        $issues = [];
        foreach (config('database.connections') as $name => $config) {
            if (($config['driver'] ?? '') === 'mysql') {
                if (empty($config['options'][\PDO::MYSQL_ATTR_SSL_CA])) {
                    $issues[] = "Connection '{$name}' does not use SSL";
                }
            }
        }

        if (!empty($issues)) {
            return CheckResult::failed(
                'Database connections without SSL detected',
                ['connections' => $issues],
                'Add SSL options to config/database.php for production connections'
            );
        }

        return CheckResult::passed('All database connections use SSL');
    }
}
```

Register it in a service provider:

```
use FilaStudio\Vigil\SecurityScanner;

public function boot()
{
    app(SecurityScanner::class)->registerCheck(new \App\Security\Checks\DatabaseSSLCheck());
}
```

After that, `php artisan vigil:audit` will include your check alongside the built-in ones.

`CheckResult` has four static constructors: `passed()`, `failed()`, `warning()`, `skipped()`. Use `skipped()` when a check doesn't apply to the current environment.

### Enums

[](#enums)

PHP 8.2 backed enums are available for type-safe values:

- `CheckStatus`: `Passed`, `Failed`, `Warning`, `Skipped`
- `Severity`: `Critical`, `High`, `Medium`, `Low`, `Info`
- `Category`: `Filesystem`, `Configuration`, `HttpHeaders`, `Dependencies`, `Extended`

Cleanup
-------

[](#cleanup)

Scan results accumulate in the database over time. The retention period is configurable:

```
// config/vigil.php
'results_retention_days' => 90,
```

To delete records older than the retention period:

```
app(SecurityScanner::class)->cleanupOldScans();
```

Or schedule it:

```
// app/Console/Kernel.php
$schedule->call(function () {
    app(\FilaStudio\Vigil\SecurityScanner::class)->cleanupOldScans();
})->weekly();
```

CI/CD Integration
-----------------

[](#cicd-integration)

The `--fail-on` flag makes Vigil work as a pipeline gate. If any check with the specified severity fails, the command exits with code 1.

```
php artisan vigil:audit --fail-on=critical,high
```

GitHub Actions example:

```
- name: Security Audit
  run: php artisan vigil:audit --fail-on=critical,high
```

GitLab CI:

```
security_audit:
  stage: test
  script:
    - php artisan vigil:audit --fail-on=critical,high
```

Jenkins:

```
sh 'php artisan vigil:audit --fail-on=critical,high'
```

You can adjust the threshold: `--fail-on=critical` for lenient, `--fail-on=critical,high,medium` for strict.

Development
-----------

[](#development)

```
# Tests (PestPHP)
composer test

# Code style (Laravel Pint)
composer pint:test

# Static analysis (PHPStan level 8)
composer phpstan

# All at once
composer test && composer pint:test && composer phpstan
```

Contributing
------------

[](#contributing)

Pull requests are welcome.

License
-------

[](#license)

MIT. See [LICENSE](LICENSE.md).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance76

Regular maintenance activity

Popularity17

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

132d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/73c26ff1c1a198d7e1dd5172e61af04080872979a3ebef5acb06047e0433015e?d=identicon)[filastudio](/maintainers/filastudio)

---

Top Contributors

[![filastudio](https://avatars.githubusercontent.com/u/263184661?v=4)](https://github.com/filastudio "filastudio (1 commits)")

---

Tags

laravellaravel-filamentlaravel-securitylaravel-security-checkerphpsecuritysecurity-tools

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/filastudio-laravel-vigil/health.svg)

```
[![Health](https://phpackages.com/badges/filastudio-laravel-vigil/health.svg)](https://phpackages.com/packages/filastudio-laravel-vigil)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k55.4M8.5k](/packages/larastan-larastan)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k91.9k1](/packages/mike-bronner-laravel-model-caching)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M201](/packages/laravel-ai)[api-platform/laravel

API Platform support for Laravel

58171.6k14](/packages/api-platform-laravel)[masterix21/laravel-licensing

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1563.2k4](/packages/masterix21-laravel-licensing)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
