Open source
Sentinel for Laravel
composer require roundly-consulting/sentinel-for-laravelOverview
Sentinel for Laravel tells you when your data was changed behind your application’s back, and makes every request count once. It seals Eloquent models with keyed MACs or signatures, detects any change made outside the application — a SQL console, a mass update(), a restored backup — and refuses to build on a tampered row until someone acknowledges the change with a reason. Around it sit the request-integrity tools: idempotency keys, single-use nonces and URLs, and RFC 9421 HTTP message signatures. Native and MIT licensed, built only on Laravel and the Roundly Tier-0 packages package-toolkit, enums and crypto.
What you get
Tamper-evident seals
Named, typed seals on any Eloquent model, written atomically with every write and verified anywhere — with the changed columns named.
Refused until acknowledged
A row changed outside the application can’t be edited until someone accepts the change with a reason, recorded with the actor.
Append-only ledger & anchors
A MAC’d history of every seal event, folded into chained checkpoints and published to external anchors — rollbacks show up.
Key rings & rotation
HMAC-SHA-256/384/512, Ed25519 and ECDSA keys in named rings, with rotation, revocation, retirement and runtime partner imports.
Idempotency keys
Idempotency-Key handling for HTTP routes, queued jobs and programmatic runs — repeats get the first response, never a second charge.
Nonces & HTTP signatures
Single-use nonces and signed URLs, plus RFC 9421 HTTP message signatures for inbound and outbound requests.
Facade, DI or actions
One Sentinel facade, an injectable SentinelManager or single-purpose actions — plus a recording fake that keeps production semantics.
Documentation
Installation
Install via Composer, run the guided sentinel:install, settle the morph key types, migrate, create the first key and baseline existing rows.
Configuration
Every config key with its default and env variable — keys and rings, sealing, verification, ledger and anchors, idempotency, nonces, signatures, schedule.
What it detects
What Sentinel detects, against which attacker, with and without an external anchor — and what it deliberately does not guarantee.
Declaring seals
Declare named, typed seals on a model — the builder, field types and cast inference, computed values, reusable definitions and compile errors.
The Sentinel facade
The Sentinel facade — the for($model) handle, flat seal verbs, model-wide operations and the keys, ledger, idempotency, nonces and signatures accessors.
DI and actions
Skip the facade: inject SentinelManager or call one of the 28 host-facing actions — request objects, plain-argument actions and the method → action map.
Sealing and writes
When rows are sealed, how a write and its seal commit atomically, writes to a tampered row, deletes, suspension and save() overrides.
Verifying
Verify one seal, every seal or many models — results, statuses and reasons, status precedence, changed attributes, verify-on-retrieve and scans.
Acknowledging changes
Accept an out-of-band change with a reason and an actor, gate who may do it, unseal deliberately and load a tampered row for review.
Bulk operations
Scan, re-seal, baseline and mass-update every row of a model — re-sealing never launders, and a verified mass update writes all or nothing.
Ledger, checkpoints and anchors
The append-only ledger, chained checkpoints and external anchors that make deleted or rolled-back history detectable — and how to verify them.
Middleware, rule and scopes
Verify route models with sentinel.verified, validate input with IntactSeal, check whole collections with verifySeals() and query by seal state.
Idempotency keys
Idempotency-Key handling for routes, programmatic runs for jobs and webhooks, the Idempotent job middleware and the client macro.
Nonces and single-use URLs
Purpose-bound single-use tokens and single-use signed URLs — only a hash is stored, and consumption is one atomic statement.
HTTP message signatures
Verify partners’ RFC 9421 signed requests, sign outbound calls, check signed responses — partner keys, profiles, rejections and signing options.
Key management
Key rings, drivers and algorithms; generate, import, rotate, revoke and retire keys; statuses, verify-only nodes and partner imports.
Commands and health check
Every sentinel:* command with its options and exit codes, the self-registering schedule and the ten-check health report.
Events
Every event Sentinel dispatches, when it fires and what it carries — scalar, queue-safe payloads with helpers to load the model.
Extending
Plug in a KMS key store or a custom anchor, and bind your own idempotency and nonce stores, scope resolver or acknowledgement policy.
Exceptions, statuses and enums
Every exception and when it is thrown, the HTTP problem responses, verification status values and every enum Sentinel ships.
Database schema
The six sentinel_ tables, their connections and foreign keys, the read-side models, factories, retention and the database grants to apply.
Canonical format
The frozen sentinel.seal/1 format: what gets MAC’d, how every value type is normalized, the seal document and the field tags.
Testing
Swap in Sentinel::fake() to script statuses and assert every call, or run real seals in your suite with WithSentinelKeys.
Standards
The standards Sentinel implements — HMAC, HKDF, JCS, EdDSA and ECDSA, RFC 9421, 9530, 9651 and 9457, NIST key management — and how each is proven.
Requirements
PHP 8.4+ with ext-hash and ext-mbstring, Laravel 12 or 13, and SQLite, PostgreSQL or MySQL; ext-sodium for Ed25519 keys.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.