Skip to content

omniauth/webauthn API reference

Floor
Provider · Omniauth
Version
1.x
Conformance suite
not wired
Verified for real
Verified in part
Licence
MIT
composer require omniauth/webauthn:1.x-dev

Read from the package's own PHP files at the commit 21b1a4b36943: its namespaces, classes, interfaces and enums, their public constants, properties and methods with their PHPDoc, and the options its factories take. Nothing of it is run.

Omniauth\WebAuthn

  • PasskeyMethod class

    Passkeys (WebAuthn) over web-auth/webauthn-lib, framework-free: a first factor, after which no second one is asked (Marco's decision QA1: it proves the device and the gesture or the code that unlocks it - user verification is required at every ceremony).

    7 methods · 2 constants

  • PasskeyRecord class

    A passkey as omnibase's userPasskey table holds it: the 13 fields of WebAuthn's credential record (webauthn-lib's Webauthn\CredentialRecord), under the same names, in the values of the columns - the credential id and the public key in standard base64 with its padding (the text of the bundle's `base64` type and of omnibase's `passkey_base64`), the AAGUID as its text, the trust path as the array webauthn-lib normalizes it to (`[]`, or `['x5c' => [...]]`). A row written by web-auth/webauthn-symfony-bundle is a record here (fromRow()), and a record made here is a row the bundle reads (toRow()); toCredentialRecord() and fromCredentialRecord() do what omnibase's PasskeyRepository does.

    8 methods · 13 properties · 1 constant

  • RelyingParty class

    Who the passkeys belong to: the relying party's id (a registrable domain: a passkey made for it serves every host under it), the name some authenticators show, and the origins a ceremony may come from.

    5 methods · 4 properties

Omniauth\WebAuthn\Contract

  • Passkeys interface

    The passkeys of the application's accounts (omnibase: the userPasskey table, Base\Entity\User\Passkey), as PasskeyRecord values.

    4 methods

Omniauth\WebAuthn\Testing

  • InMemoryPasskeys class

    The passkeys in memory, by credential id: tests, the harness's bare script, a first try in plain PHP.

    5 methods · 3 properties

  • SoftwareAuthenticator class

    A passkey authenticator in PHP, for tests (the one lesringostars' sign-in characterisation used, plan "omniauth" AU0): a P-256 key made by OpenSSL, which answers the options a site gives with the JSON a browser's PublicKeyCredential.toJSON() posts - attestation "none" at a registration, an ES256 signature at a sign-in. The person is present and verified (the flags UP and UV) unless told otherwise; nothing is backed up unless told.

    8 methods · 5 properties

Omniauth\WebAuthn

PasskeyMethod class

final class PasskeyMethod implements Challenging, Enrolling PasskeyMethod.php:62

Passkeys (WebAuthn) over web-auth/webauthn-lib, framework-free: a first factor, after which no second one is asked (Marco's decision QA1: it proves the device and the gesture or the code that unlocks it - user verification is required at every ceremony).

Signing in: begin() gives the request options (a 32-byte challenge, the relying party's id, user verification required, no list of credentials: a discoverable passkey, the person picks it), as the JSON webauthn-lib's serializer writes - the JSON assets/security/webauthn.js parses today with PublicKeyCredential.parseRequestOptionsFromJSON(); verify() takes what the browser's credential.toJSON() posts (['json' => ...], or its keys as the proof), finds the passkey by its id, has webauthn-lib check the assertion (challenge, origin, relying party, presence and verification, signature, counter, backup flags) and saves the counter and the flags (Passkeys::used()).

Registering, from the settings: enrolBegin() gives the creation options for the account (its handle as the user's id, its identifier and display name, its passkeys excluded); enrolConfirm() has webauthn-lib check the attestation and adds the record (['label' => ...] names it).

What a ceremony remembers between its two steps (the challenge, the relying party's id) stays in the attempt, never in the answer; a challenge serves once.

const CHALLENGE_LENGTH = 32
const ALGORITHMS = [-7, -257]

What webauthn-lib checks by default: ES256, RS256.

PasskeyMethod::__construct()

public function __construct(readonly Accounts $accounts, readonly Passkeys $passkeys, readonly RelyingParty $rp = new RelyingParty(), readonly ?int $timeout = null)
$timeout

milliseconds the browser gives the person, null for its own

PasskeyMethod::factor()

public function factor(): Factor

PasskeyMethod::begin()

public function begin(Attempt $attempt, Proof $proof, Context $context): Challenge

PasskeyMethod::verify()

public function verify(Attempt $attempt, Proof $proof, Context $context): Verdict

PasskeyMethod::enrolBegin()

public function enrolBegin(Attempt $enrolment, Proof $proof, Context $context): Challenge

PasskeyMethod::enrolConfirm()

public function enrolConfirm(Attempt $enrolment, Proof $proof, Context $context): Enrolled

PasskeyMethod::serializer()

public function serializer(): SerializerInterface

The serializer webauthn-lib reads and writes its JSON with (the host may parse a posted credential with it).

PasskeyRecord class

final readonly class PasskeyRecord PasskeyRecord.php:25

A passkey as omnibase's userPasskey table holds it: the 13 fields of WebAuthn's credential record (webauthn-lib's Webauthn\CredentialRecord), under the same names, in the values of the columns - the credential id and the public key in standard base64 with its padding (the text of the bundle's base64 type and of omnibase's passkey_base64), the AAGUID as its text, the trust path as the array webauthn-lib normalizes it to ([], or ['x5c' => [...]]). A row written by web-auth/webauthn-symfony-bundle is a record here (fromRow()), and a record made here is a row the bundle reads (toRow()); toCredentialRecord() and fromCredentialRecord() do what omnibase's PasskeyRepository does.

Immutable: after a sign-in, Passkeys::used() receives the record with its counter and backup flags moved (after()).

const NO_AAGUID = '00000000-0000-0000-0000-000000000000'

The AAGUID of an authenticator that names no model (attestation "none").

public string $publicKeyCredentialId

The credential's id: base64 of its bytes, as the column keeps it.

public string $type
public array $transports

how the browser reaches the authenticator ("internal", "usb", "hybrid"...)

public string $attestationType
public array $trustPath

[] for none, ['x5c' => [...]] for a chain of certificates

public string $aaguid
public string $credentialPublicKey

The public key: base64 of its COSE bytes.

public string $userHandle

The account's handle (Accounts::handle(), its id as text).

public int $counter

The signature counter the authenticator last gave.

public ?array $otherUI
public ?bool $backupEligible
public ?bool $backupStatus
public ?bool $uvInitialized

PasskeyRecord::__construct()

public function __construct(public string $publicKeyCredentialId, public string $type = 'public-key', public array $transports = [], public string $attestationType = 'none', public array $trustPath = [], public string $aaguid = self::NO_AAGUID, public string $credentialPublicKey = '', public string $userHandle = '', public int $counter = 0, public ?array $otherUI = null, public ?bool $backupEligible = null, public ?bool $backupStatus = null, public ?bool $uvInitialized = null)
$transports

how the browser reaches the authenticator ("internal", "usb", "hybrid"...)

$trustPath

[] for none, ['x5c' => [...]] for a chain of certificates

PasskeyRecord::credentialId()

public function credentialId(): string

The credential id's bytes.

PasskeyRecord::publicKey()

public function publicKey(): string

The public key's COSE bytes.

PasskeyRecord::toCredentialRecord()

public function toCredentialRecord(): CredentialRecord

webauthn-lib's record of this passkey: what a ceremony is checked against (omnibase's PasskeyRepository::credentialRecord()).

PasskeyRecord::fromCredentialRecord()

public static function fromCredentialRecord(CredentialRecord $record): self

The record of what webauthn-lib made or moved (omnibase's PasskeyRepository::fill()).

PasskeyRecord::after()

public function after(CredentialRecord $checked): self

This passkey after a sign-in webauthn-lib checked: its counter and its flags as the assertion left them.

PasskeyRecord::fromRow()

public static function fromRow(array $row): self

A row of the userPasskey table, as the database gives it back: the JSON columns as their text (or decoded), the booleans as 0/1 or bools, the counter as a number or its text. Other columns (id, user_id, label, dates) are ignored.

PasskeyRecord::toRow()

public function toRow(): array

The 13 columns as the bundle's DBAL types (and omnibase's) write them: base64 text, the JSON columns encoded as Doctrine's JSON type encodes them, the booleans as 0/1 (or null), the counter as a number.

RelyingParty class

final readonly class RelyingParty RelyingParty.php:19

Who the passkeys belong to: the relying party's id (a registrable domain: a passkey made for it serves every host under it), the name some authenticators show, and the origins a ceremony may come from.

By Marco's decision QA9 (2026-10-20), the Symfony site and its Laravel twin share one registrable domain in production: the id is that domain (RELYING_PARTY_ID), and the origins are both hosts'. With no id, each request's host is the id; with no origins, each request's origin is the only one allowed. The port never enters the id ("localhost" for https://localhost:8443 and http://localhost:8132 alike).

public ?string $id
public ?string $name
public array $origins

the origins allowed (https://www.example.org, https://twin.example.org), [] for the request's own

public array $insecure

the ids allowed over plain http (WebAuthn's own exception: localhost)

RelyingParty::__construct()

public function __construct(public ?string $id = null, public ?string $name = null, public array $origins = [], public array $insecure = ['localhost'])
$origins

the origins allowed (https://www.example.org, https://twin.example.org), [] for the request's own

$insecure

the ids allowed over plain http (WebAuthn's own exception: localhost)

RelyingParty::id()

public function id(Context $context): string

The relying party's id for this request: the one set, else the request's host (lower case, no port).

RelyingParty::name()

public function name(Context $context): string

The name an authenticator shows: the one set, else the id (as web-auth/webauthn-symfony-bundle without rp.name).

RelyingParty::origins()

public function origins(Context $context): array

RelyingParty::serves()

public function serves(Context $context): bool

May this request's host use the id? WebAuthn asks the id to be the host or a domain it is under (a browser refuses otherwise).

Omniauth\WebAuthn\Contract

Passkeys interface

interface Passkeys Passkeys.php:11

The passkeys of the application's accounts (omnibase: the userPasskey table, Base\Entity\User\Passkey), as PasskeyRecord values.

Passkeys::of()

public function of(object $account): iterable
Returns

the account's passkeys (a registration excludes them)

Passkeys::byCredentialId()

public function byCredentialId(string $credentialId): ?PasskeyRecord
$credentialId

the credential's id in base64, as the table keeps it

Passkeys::add()

public function add(object $account, PasskeyRecord $record, ?string $label = null): void

A passkey registered for the account, under the name the person gave it (if any).

Passkeys::used()

public function used(PasskeyRecord $record): void

After a sign-in: the counter and the backup flags as the assertion left them (and the host's last-used date).

Omniauth\WebAuthn\Testing

InMemoryPasskeys class

final class InMemoryPasskeys implements Passkeys InMemoryPasskeys.php:10

The passkeys in memory, by credential id: tests, the harness's bare script, a first try in plain PHP.

public array $records = []
public array $labels = []
public array $uses = []

InMemoryPasskeys::__construct()

public function __construct(readonly Accounts $accounts)

InMemoryPasskeys::of()

public function of(object $account): iterable

InMemoryPasskeys::byCredentialId()

public function byCredentialId(string $credentialId): ?PasskeyRecord

InMemoryPasskeys::add()

public function add(object $account, PasskeyRecord $record, ?string $label = null): void

InMemoryPasskeys::used()

public function used(PasskeyRecord $record): void

SoftwareAuthenticator class

final class SoftwareAuthenticator SoftwareAuthenticator.php:16

A passkey authenticator in PHP, for tests (the one lesringostars' sign-in characterisation used, plan "omniauth" AU0): a P-256 key made by OpenSSL, which answers the options a site gives with the JSON a browser's PublicKeyCredential.toJSON() posts - attestation "none" at a registration, an ES256 signature at a sign-in. The person is present and verified (the flags UP and UV) unless told otherwise; nothing is backed up unless told.

No library: its CBOR is the little WebAuthn needs. A host's tests sign in with it under Symfony and Laravel alike, with no browser.

public readonly string $credentialId
public int $counter
public bool $verified
public bool $backupEligible
public bool $backedUp

SoftwareAuthenticator::__construct()

public function __construct(readonly string $origin, ?string $privateKey = null, ?string $credentialId = null, public int $counter = 0, public bool $verified = true, public bool $backupEligible = false, public bool $backedUp = false)
$origin

the page's origin, as the browser writes it in the client data (https://example.org)

$privateKey

a PEM P-256 key, to be the same authenticator from one run to another; a new key otherwise

$credentialId

the credential's bytes; 32 random bytes otherwise

SoftwareAuthenticator::create()

public function create(string|array $options): array

navigator.credentials.create() on the creation options (their JSON, or decoded).

SoftwareAuthenticator::get()

public function get(string|array $options): array

navigator.credentials.get() on the request options (their JSON, or decoded).

SoftwareAuthenticator::publicKey()

public function publicKey(): string

The credential's public key, COSE (RFC 9053: EC2, ES256, P-256), as a credential record keeps it.

SoftwareAuthenticator::privateKey()

public function privateKey(): string

The private key, PEM: to be this authenticator again later (new self($origin, $authenticator->privateKey(), $authenticator->credentialId)).

SoftwareAuthenticator::belongsTo()

public function belongsTo(string $userHandle): self

The account this authenticator's credential belongs to (what create() learns from the options): the userHandle it sends.

SoftwareAuthenticator::encode()

public static function encode(string $bytes): string

base64url without padding, as WebAuthn's JSON writes bytes.

SoftwareAuthenticator::decode()

public static function decode(string $base64url): string