The passkey plugin implements FIDO2/WebAuthn authentication, allowing users to register and authenticate with biometrics, security keys, or platform authenticators. It wraps the go-webauthn/webauthn library and manages credential storage, registration ceremonies, and authentication ceremonies.
Setup01
import (
"github.com/xraph/authsome"
"github.com/xraph/authsome/plugins/passkey"
)
eng, err := authsome.NewEngine(
authsome.WithStore(store),
authsome.WithPlugin(passkey.New(passkey.Config{
RPDisplayName: "My App",
RPID: "example.com",
RPOrigins: []string{"https://example.com"},
SessionTimeout: 5 * time.Minute,
})),
)Configuration02
| Option | Type | Default | Description |
RPDisplayName | string | "AuthSome" | Relying party display name shown during WebAuthn ceremonies |
RPID | string | "localhost" | Relying party identifier, typically the domain name |
RPOrigins | []string | [] | Allowed origins for WebAuthn ceremonies |
SessionTimeout | time.Duration | 5m | How long a WebAuthn ceremony session remains valid |
Implemented interfaces03
| Interface | Purpose |
Plugin | Base plugin identity ("passkey") |
OnInit | Initializes the WebAuthn library and captures bridges |
RouteProvider | Registers registration and authentication endpoints |
MigrationProvider | Contributes the passkey_credentials table |
AuthMethodContributor | Reports registered passkeys as linked auth methods |
Registration ceremony04
The registration ceremony creates a new passkey credential for the authenticated user.
Step 1: Begin registration
POST /v1/auth/passkey/register/begin
The server generates a challenge and returns PublicKeyCredentialCreationOptions for the browser's navigator.credentials.create() API.
{
"publicKey": {
"rp": {"name": "My App", "id": "example.com"},
"user": {"id": "base64...", "name": "alice", "displayName": "Alice"},
"challenge": "base64...",
"pubKeyCredParams": [
{"type": "public-key", "alg": -7},
{"type": "public-key", "alg": -257}
],
"authenticatorSelection": {
"residentKey": "preferred",
"userVerification": "preferred"
}
}
}Step 2: Complete registration
POST /v1/auth/passkey/register/finish
The client sends the AuthenticatorAttestationResponse from the browser. The server validates the attestation, extracts the public key, and stores the credential.
{
"id": "base64-credential-id",
"rawId": "base64-raw-id",
"response": {
"clientDataJSON": "base64...",
"attestationObject": "base64..."
},
"type": "public-key"
}Authentication ceremony05
The authentication ceremony verifies the user's passkey credential.
Step 1: Begin authentication
POST /v1/auth/passkey/login/begin
Returns PublicKeyCredentialRequestOptions for navigator.credentials.get().
Step 2: Complete authentication
POST /v1/auth/passkey/login/finish
The client sends the AuthenticatorAssertionResponse. The server verifies the signature against the stored public key, updates the sign count, and creates a session.
Credential types06
Resident keys (discoverable credentials)
When residentKey is set to "required" or "preferred", the authenticator stores the credential internally. Users can authenticate without entering a username first -- the authenticator presents all stored credentials for the relying party.
Non-resident keys
The server must provide a list of allowed credential IDs during authentication. The user must first identify themselves (e.g., by entering an email) so the server can look up their credentials.
Platform vs roaming authenticators
Platform authenticators -- Built into the device (Touch ID, Face ID, Windows Hello). Use
authenticatorAttachment: "platform"to prefer these.Roaming authenticators -- External security keys (YubiKey, SoloKeys). Use
authenticatorAttachment: "cross-platform".
Credential storage07
Each registered credential stores:
| Field | Description |
CredentialID | Unique identifier for the credential |
PublicKey | The credential's public key (used for signature verification) |
AttestationType | Attestation type from the registration response |
Transport | Supported transports (usb, nfc, ble, internal) |
SignCount | Monotonically increasing counter for clone detection |
AAGUID | Authenticator Attestation GUID |
DisplayName | User-provided label for the credential |
Auth method reporting08
The passkey plugin implements AuthMethodContributor, returning one entry per registered credential:
{
"type": "passkey",
"provider": "passkey",
"label": "MacBook Pro Touch ID",
"linked_at": "2024-11-01T10:00:00Z"
}API routes09
| Method | Path | Description |
POST | /v1/auth/passkey/register/begin | Start passkey registration ceremony |
POST | /v1/auth/passkey/register/finish | Complete passkey registration |
POST | /v1/auth/passkey/login/begin | Start passkey authentication ceremony |
POST | /v1/auth/passkey/login/finish | Complete passkey authentication |
GET | /v1/auth/passkey/credentials | List user's registered passkeys |
DELETE | /v1/auth/passkey/credentials/:id | Remove a registered passkey |
Ceremony state management10
WebAuthn ceremonies require server-side state between the begin and finish steps. The passkey plugin uses the engine's ceremony store (defaulting to in-memory) to persist challenge data. For multi-instance deployments, configure a shared ceremony store (e.g., Redis-backed).