All packages
Auth for Laravel
Security
Each property below is covered by a test in the package suite.
- Enumeration — guest endpoints answer known, unknown, disabled and unverified accounts identically (status and body); mail goes only to real, active accounts, after the response. A password check always runs, against a dummy hash of the same cost for unknown accounts. Only completed logins make a device known — a reset or sign-in link requested from a device does not, nor does a re-authentication made with a (possibly stolen) access token.
- Guard isolation — a token, link, code, invitation, challenge or passkey of one guard never works on another.
- Single use — every claim is a conditional update; challenges advance with an optimistic version check and snapshot the account’s token version.
- Invalidation — tv++ kills every outstanding access token; session families are revoked, and a refresh retires the session’s previous access token, so revoking a session kills every token it minted; pending sign-in, reset, re-authentication and email-change links die with them; the jti denylist is belt-and-braces.
- Throttling — attempts are counted atomically before a password or code is checked — the login, email and re-authentication throttles, email codes and every challenge’s own max_attempts — so a burst of concurrent guesses cannot all pass the limit.
- Risk step-up — require_second_factor applies to every login method, also when after_email_login = false; an account with no factor to step up with is denied. A passkey login that counts as MFA (passkeys.satisfies_mfa) already is the step-up.
- Re-authentication — accounts with a second factor must re-authenticate with it; a password or email-code proof, or a login that skipped the factor, never satisfies a gate for them — also when the factor was enrolled after that proof. reauthentication.methods is checked against the factor that actually matched.
- Secrets at rest — HMAC-SHA-256 with a key derived from APP_KEY (or hash_key); plaintext exists only in the response or the notification.
- Account recovery — last-credential protection, forced enrolment only for verified addresses, email changes verified and announced twice, a reset never bypasses an enrolled second factor and registration never skips required two-factor enrolment.
- Transport — Cache-Control: no-store on every package response, encrypted queued notifications and secrets in URL fragments.
Known limits
- The denylist lives in cache — a flush revives revoked, unexpired access tokens until they expire. The token version covers invalidations; a short access_ttl bounds the rest.
- Forced enrolment — a password-only attacker could enrol their own factor under a required mode; mitigated by the verified-address gate and notifications, and a challenge whose enrolment step went stale (the factor was set up meanwhile) is ended.
- Registration with immediate tokens reveals a taken address — use the enumeration-safe modes.
- One passkeys relying party for all guards, and one key type for every guard model.
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.