Open source
Passkeys for Laravel
composer require roundly-consulting/passkeys-for-laravelOverview
A native WebAuthn / FIDO2 passkey relying party for Laravel. It builds the options the browser needs, verifies the signed responses that come back, and stores each credential against the right user — following the WebAuthn Level 2 ceremonies, with ES256, RS256 and EdDSA credentials. It is deliberately controller-less: your application keeps its routes, UI, throttling and session or token issuance. MIT-licensed, with no third-party crypto — the cryptography runs on Roundly’s own crypto-for-laravel.
What you get
Facade, DI or actions
Two-call ceremonies on the Passkeys facade — or inject PasskeyService, or run the single-purpose actions directly.
Usernameless & second factor
Discoverable login by default; user-bound options and owner expectations for step-up and multi-guard apps.
No third-party crypto
ES256, RS256 and opt-in EdDSA verified through Roundly’s own crypto-for-laravel — no external WebAuthn library.
Attestation trust ladder
ignore, self or basic — packed and Apple formats, shipped Apple and Google roots, AAGUID allow-lists. Configuration, not code.
Hardened by default
Single-use, ceremony-bound challenges, origin and RP ID checks, a forward-only sign counter for clone detection and no user enumeration.
Ownership-checked management
Passkeys::for($user) lists, renames and revokes only that account’s passkeys — plus a display-safe PasskeyResource and audit events.
Testing built in
A recording Passkeys::fake() with assertions for every ceremony, plus a software VirtualAuthenticator for real end-to-end runs.
Documentation
Installation
Install via Composer, publish and run the migrations, then set the relying-party ID and the allowed origins.
Configuration
Every config key with its env variable and default — relying party, origins, algorithms, challenges, attestation trust and user wiring.
User model
Add the opaque user-handle column, implement HasPasskeys with the InteractsWithPasskeys trait, and run ceremonies straight off the user.
The Passkeys facade
The whole public API on one facade — Passkeys::for($user) for everything scoped to an account, flat calls for the usernameless login.
DI and actions
Inject PasskeyService for the same API without static calls, or run a ceremony’s single-purpose action directly from trusted code.
Registration
Build creation options for navigator.credentials.create(), verify the attestation response and persist the credential with a friendly name.
Authentication
Usernameless or user-bound sign-in — build request options, verify the assertion and start your own session from the resolved credential.
Second factor & owner expectations
Ask a known account for its own passkey, demand user verification for one step, and restrict sign-in to one owner type in multi-guard apps.
Managing passkeys
Everything a “your passkeys” screen needs — list, rename and revoke credentials, and serialise them safely with PasskeyResource.
Passkey model & schema
The soft-deleting, polymorphic Passkey model — scopes, casts, hidden attributes, the table schema and swapping in your own model.
Algorithms & Ed25519
ES256 and RS256 out of the box, Ed25519 (EdDSA) as an opt-in with ext-sodium — and no unvetted algorithm is ever accepted.
Attestation
Prove what an authenticator is — a three-tier trust ladder, packed and Apple formats, shipped roots and AAGUID allow-lists, all in config.
Events
Five events for audit trails and anomaly handling — registered, authenticated, counter regressed, revoked and renamed.
Exceptions
One PasskeyException base with typed children for ceremony, configuration, decoding and attestation failures — with localisable messages.
Enums
Reference for every enum — user verification, resident key, attachment, attestation conveyance, trust and type, sign-count policy.
Extending
Swap the challenge store, add an attestation format, replace the trust policy or implement HasPasskeys yourself — all through container bindings.
Security model
What the relying party enforces on every ceremony — challenges, origins, signatures, counters, enumeration — and what it leaves to you.
Testing
Record and assert ceremonies with Passkeys::fake(), or run real ceremonies end to end with the software VirtualAuthenticator.
Requirements
PHP 8.4+, Laravel 12 or 13 and ext-json — plus ext-sodium only if you enable Ed25519 credentials.
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.