All packages
Passkeys for Laravel
Exceptions
Every failure extends RoundlyConsulting\Passkeys\Exceptions\PasskeyException (a RuntimeException). Catch the base for a uniform response, or a child for finer control:
use RoundlyConsulting\Passkeys\Exceptions\PasskeyException;
try {
$passkey = Passkeys::authenticate($response);
} catch (PasskeyException $e) {
// Return a uniform failure to the client; log $e server-side.
return response()->json(['message' => 'Sign-in failed.'], 422);
}Ceremony failures
| Exception | Thrown when |
|---|---|
InvalidClientData | clientData.type is wrong, the response payload is malformed, the attestation fmt is not a well-formed format identifier, or a user handle is not base64url of random bytes. |
ChallengeExpired | No challenge exists for the ceremony ID — expired or already used. |
ChallengeMismatch | The challenge differs, was minted for another user, or for the other ceremony type. |
OriginMismatch | The origin is not allow-listed, or a cross-origin ceremony is not allowed. |
RpIdMismatch | The RP ID hash in the authenticator data doesn’t match. |
InvalidAuthenticatorData | Bad authenticator data, no user-presence flag, inconsistent backup flags, a backup eligibility that differs from the one registered, or missing attested credential data. |
UserVerificationRequired | User verification was required but the authenticator didn’t verify the user. |
UnsupportedAlgorithm | The credential’s algorithm isn’t in the offered list. |
SignatureInvalid | The assertion signature failed verification. |
SignCountRegression | The counter didn’t advance and sign_count_policy is reject. |
CredentialAlreadyRegistered | The credential ID is already stored, revoked ones included. |
CredentialNotFound | The uniform miss: an unknown credential, one a user-bound ceremony didn’t offer, a usernameless assertion without a userHandle, a failed expectation, a credential revoked mid-assertion, or a rename/revoke of a passkey that isn’t this account’s. |
InvalidExpectation | AuthenticationExpectation::owner() got an unsaved model — a programming error, never a ceremony outcome. |
Configuration, decoding and attestation
| Exception | Thrown when |
|---|---|
InvalidConfiguration | At boot: a config value of the wrong shape, naming the key (table only when first read), an unvetted algorithm, trust stricter than ignore with attestation none, or clock skew outside 0–3600. At the first ceremony: missing rp.id or origins. At first use: an unreadable trust anchor. |
MalformedCbor | The CBOR data is malformed. |
InvalidCoseKey | The COSE public key is invalid. |
InvalidAttestation | The attestation statement’s maths failed. |
AttestationUntrusted | The statement is sound but policy refused it — unanchored root, no anchors configured, self-attestation under basic, an invalid certification path, an expired certificate or a disallowed AAGUID. |
AttestationRequired | The trust tier demands a statement and the authenticator sent none. |
UnsupportedAttestationFormat | The format has no verifier (none, packed and apple are supported). |
PasskeyAssertionFailed | A Passkeys::fake() assertion failed. |
Messages resolve through the passkeys::errors.* translation namespace — publish passkeys-translations to localise them.
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.