sentinel-laravel maintained by redeyed
Redeyed Sentinel for Laravel
Add Redeyed Sentinel — a self-hosted CAPTCHA + IP-reputation service — to any Laravel app in a couple of minutes.
Sentinel is free to install and completely inert until you set your keys. Before keys are configured the package fails open (verification passes and a warning is logged) so your forms never break. Once your keys are in place, every protected form is verified server-side.
Requirements
- PHP >= 8.1
- Laravel 10 or 11
Installation
composer require redeyed/sentinel-laravel
The service provider is auto-discovered — there is nothing to register manually.
Optionally publish the config:
php artisan vendor:publish --tag=sentinel-config
Configuration
Grab your keys from the Redeyed Lab panel:
- Site key (public): Developer → Sentinel Sites
- API key (secret): Developer → API Keys
Add them to your .env:
SENTINEL_SITE_KEY=your-public-site-key
SENTINEL_API_KEY=your-secret-api-key
# Optional — only change if you self-host Sentinel elsewhere
# SENTINEL_BASE_URL=https://redeyed.com
The SENTINEL_API_KEY is secret and stays server-side — it is only ever
sent as the X-Api-Key header during verification and is never exposed to the
browser.
Usage
1. Render the widget in your form
Drop the component anywhere inside your <form>:
<form method="POST" action="/register">
@csrf
{{-- ...your fields... --}}
<x-sentinel-captcha />
<button type="submit">Submit</button>
</form>
Prefer a directive? @sentinel does exactly the same thing:
<form method="POST" action="/register">
@csrf
@sentinel
<button type="submit">Submit</button>
</form>
The widget loads the Sentinel script once per page and injects a hidden input
named sentinel-token into your form.
2. Verify on the server
Add the rule to your validation. Either use the rule class:
use Redeyed\LaravelSentinel\Rules\Sentinel;
$request->validate([
// ...your other rules...
'sentinel-token' => ['required', new Sentinel],
]);
…or the string alias:
$request->validate([
'sentinel-token' => ['required', 'sentinel'],
]);
If verification fails the user sees:
Human verification failed — please try again.
How verification works
On submit, the package POSTs to {BASE_URL}/api/v1/verify with the
X-Api-Key header and a JSON body of {"site_key": "...", "token": "..."}.
The submission passes only when the response reports success === true
(both the { "data": { "success": true }, "meta": {} } envelope and a flat
{ "success": true } shape are supported).
If keys are not configured, verification fails open and logs a warning so forms keep working until you finish setup.
License
MIT © 2026 Redeyed Corporation