marshmallow/ip-access
marshmallow/ip-access is a Laravel package for IP-based access control. It lets you protect routes with configurable allowlists and denylists, supporting individual IP addresses, CIDR ranges, and middleware-driven rules for simple, centralized request filtering.
This assessment is based on the v2.8.0 release notes only (no prior review, no repo metadata). The package provides IP-whitelist access control for Laravel via middleware, a config whitelist, and an IPACCESS_WHITELIST env variable. Substitute <vendor>/<package> with the actual Packagist name.
Install
composer require <vendor>/<package>
As of v2.8.0, laravel/nova is not installed for you. You onlyneed it if you want the bundled Nova resource to manage whitelist entries in the UI:
composer require laravel/nova # optional
Publish and read the config
php artisan vendor:publish --provider="<Vendor>\<Package>\<Package>ServiceProvider"
Open the published config first — it is the source of truth for whitelist storage, response behaviour, and any bypass rules. Then read the middleware class to confirm exactly which request attribute it inspects (see Gotchas on proxies).
Set the whitelist
IPACCESS_WHITELIST="203.0.113.10,203.0.113.11,10.0.0.0/8"
Or edit the whitelist array in the config file. Pick one; do not maintain both.
Register the middleware
bootstrap/app.php → ->withMiddleware(fn ($m) => $m->alias(['ipaccess' => ...])), or append globally.app/Http/Kernel.php.First use case — lock down an admin surface:
Route::middleware('ipaccess')->prefix('admin')->group(function () {
// ...
});
Then hit the route from a non-whitelisted IP and confirm the rejection response (403 or redirect, per config) before rolling it out further.
ipaccess to /admin, /internal, or /horizon is usually the right granularity. Global registration locks the whole app, including health checks and webhook endpoints — reserve it for staging environments.auth so unauthorised IPs never touch session/DB work, but it does not replace authentication..env (or a per-environment config override) and leave the committed config with safe defaults. This is what IPACCESS_WHITELIST is for — treat the config array as the fallback.NovaServiceProvider::resources() so operators can add/remove IPs without a deploy. If Nova is absent, skip this entirely — nothing else in the package depends on it. This makes a good pattern: env var for static infrastructure ranges, Nova for ad-hoc operational entries.Gate::define('internal-only', ...) guard for a sensitive export endpoint — rather than blocking an entire route group.$this->withoutMiddleware(IpAccess::class) (or the alias) in feature tests so IP rules don't leak into your test suite, and add one dedicated test that spoofs REMOTE_ADDR to assert the rejection path.php artisan config:cache is standard in deploy pipelines; any .env change to IPACCESS_WHITELIST requires a re-cache (or config:clear) to take effect.$request->ip() is the proxy address unless TrustProxies is configured. Whitelisting your users' IPs then silently blocks everyone (or allows the proxy). Fix TrustProxies first, then debug the package.IPACCESS_WHITELIST is comma-separated — watch for spaces, trailing commas, and quoted values in .env. Also confirm precedence between the env var and the config array so you don't end up debugging a value that was overridden.env() outside config files. If the package calls env('IPACCESS_WHITELIST') directly rather than through a config key, it returns null once the config is cached. Verify the read path; if it's direct, that's a bug worth reporting.::ffff:203.0.113.10) compared against a plain IPv4 string is a classic mismatch.laravel/nova pulled in transitively and now depend on the bundled resource, add it explicitly to require; otherwise the resource class won't be autoloadable. After upgrading, confirm the service provider only registers the Nova resource when the class exists (otherwise nova:install-less apps can hit a class-not-found on boot).How can I help you explore Laravel packages today?