Skip to content
← All packages

Risk Scoring for Laravel

An explainable, config-driven request risk-scoring pipeline for Laravel. Weighted signals map to graduated outcomes: allow, flag, challenge, step-up, or reject, with the reasons behind every decision.

Risk Scoring for Laravel weights independent signals, IP reputation, disposable email, bot user-agents, honeypot and submit timing, into a single score, and maps that score to a graduated outcome: allow, flag, challenge, step-up, or reject. Every decision comes with the reasons behind it, so you can tune it, explain it, and defend it.

The missing middle

Most anti-abuse tools in the Laravel ecosystem are either a single-signal hard blocker (one IP list, one honeypot) or an opaque paid cloud whose verdicts you cannot explain. Neither fits an identity platform, where a wrong block locks a real user out and a regulator may ask why you made an automated decision. This package is the middle ground: many signals, a transparent weighted score, graduated friction instead of a binary block, and a full reasons breakdown on every assessment. Self-hosted, free-core, no data leaving your server.

Free-Core Signals

Honeypot & Timing

Catches bots that fill hidden fields or submit a form in under two seconds, using the well-known spatie technique. Built in, no dependencies.

User-Agent & Headers

Flags curl, python-requests and headless clients, plus requests missing the Accept headers a real browser always sends.

Disposable & MX

A bundled throwaway-domain list catches disposable signup addresses, and an MX lookup catches domains that cannot receive mail, so the address is almost certainly fake.

IP Reputation & Tor

Addresses on many blocklists via stamparm/ipsum, refreshed with risk:refresh-ipsum, plus the official Tor exit-node list. Velocity is tracked HMAC-only in your cache.

Opt-In Providers

AbuseIPDB, Spamhaus DQS, Project Honey Pot, IPQualityScore, MaxMind GeoLite2 and HIBP plug in with your own key. An unconfigured signal contributes zero, never an error.

Custom Signals

Implement the Signal contract and add it to config. Return a SignalResult with points and a reason, or null. Impossible-travel, device fingerprints, your own heuristics.

Explainable by construction

The model is weighted-additive and deliberately not machine learning: the score is the sum of each signal points times its weight, mapped to the most severe outcome band it reaches. Defaults are all configurable: Flag at 15, Challenge at 30, Step-up at 60, Reject at 80. Allowlisted IPs and email domains bypass scoring entirely, and $assessment->reasons() tells you exactly which signals fired and why.

Monitor first, enforce later

The package ships in monitor mode: it scores and you log, but it does not act on the outcome yet. Calibrate the thresholds against your real traffic, then flip RISK_MODE=enforce. Anti-abuse tools that block on install cause outages; this one refuses to.

Built for Article 22

IP addresses and fingerprints are personal data, and GDPR Article 22 owes users explainability and human review over automated decisions. That is exactly why this scorer is transparent, not a black box: every assessment carries its reasons, with data-minimization defaults and retention guidance in the docs.