Documentation
¶
Overview ¶
Package webauthn wraps go-webauthn/webauthn to provide WebAuthn/FIDO2 passkey ceremony helpers. It imports the core auth package for types but never the reverse.
Index ¶
- Constants
- Variables
- func APICredentialToWebAuthn(c *auth.PasskeyCredential) webauthn.Credential
- func BeginConditionalLogin(wa *webauthn.WebAuthn) (*protocol.CredentialAssertion, *webauthn.SessionData, error)
- func BeginLogin(wa *webauthn.WebAuthn) (*protocol.CredentialAssertion, *webauthn.SessionData, error)
- func BeginRegistration(wa *webauthn.WebAuthn, user *User) (*protocol.CredentialCreation, *webauthn.SessionData, error)
- func CompleteLogin(ctx context.Context, wa *webauthn.WebAuthn, store Store, ...) (*auth.User, *webauthn.Credential, error)
- func CredentialToAPI(c *webauthn.Credential, userID int64, name string) *auth.PasskeyCredential
- func FinishLogin(wa *webauthn.WebAuthn, sessionData *webauthn.SessionData, ...) (webauthn.User, *webauthn.Credential, error)
- func FinishRegistration(wa *webauthn.WebAuthn, user *User, sessionData *webauthn.SessionData, ...) (*webauthn.Credential, error)
- func NewWebAuthn(rpID, rpDisplayName string, rpOrigins []string) (*webauthn.WebAuthn, error)
- func PasskeyFriendlyName(aaguid []byte, existingNames []string) string
- type AAGUIDEntry
- type Store
- type User
Constants ¶
const CeremonyTimeout = 5 * time.Minute
CeremonyTimeout is the maximum duration a user has to complete an auth ceremony.
Variables ¶
var KnownAAGUIDs = []AAGUIDEntry{
{"ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4", "Google Password Manager"},
{aaguidChromeOnMac, credNameChromeOnMac},
{"08987058-cadc-4b81-b6e1-30de50dcbe96", credNameWindowsHello},
{"9ddd1817-af5a-4672-a2b9-3e3dd95000a9", credNameWindowsHello},
{"6028b017-b1d4-4c02-b4b3-afcdafc96bb2", credNameWindowsHello},
{"dd4ec289-e01d-41c9-bb89-70fa845d4bf2", "iCloud Keychain"},
{"fbfc3007-154e-4ecc-8c0b-6e020557d7bd", "iCloud Keychain"},
{"d548826e-79b4-db40-a3d8-11116f7e8349", "Bitwarden"},
{"b5397723-31d4-4c13-b037-37be46e30e9e", "1Password"},
{"bada5566-a7aa-401f-bd96-45619a55120d", "1Password"},
{"2fc0579f-8113-47ea-b116-bb5a8db9202a", "YubiKey 5"},
{"fa2b99dc-9e39-4257-8f92-4a30d23c4118", "YubiKey 5 NFC"},
}
KnownAAGUIDs is the registry of known authenticator AAGUIDs.
Functions ¶
func APICredentialToWebAuthn ¶
func APICredentialToWebAuthn(c *auth.PasskeyCredential) webauthn.Credential
APICredentialToWebAuthn converts a PasskeyCredential to a webauthn.Credential.
func BeginConditionalLogin ¶
func BeginConditionalLogin(wa *webauthn.WebAuthn) (*protocol.CredentialAssertion, *webauthn.SessionData, error)
BeginConditionalLogin starts a WebAuthn assertion ceremony with conditional mediation, enabling browser autofill UI for passkeys.
func BeginLogin ¶
func BeginLogin(wa *webauthn.WebAuthn) (*protocol.CredentialAssertion, *webauthn.SessionData, error)
BeginLogin starts a WebAuthn assertion ceremony (discoverable login).
func BeginRegistration ¶
func BeginRegistration(wa *webauthn.WebAuthn, user *User) (*protocol.CredentialCreation, *webauthn.SessionData, error)
BeginRegistration starts a WebAuthn registration ceremony.
func CompleteLogin ¶ added in v2.1.0
func CompleteLogin(ctx context.Context, wa *webauthn.WebAuthn, store Store, sessionData *webauthn.SessionData, r *http.Request) (*auth.User, *webauthn.Credential, error)
CompleteLogin completes a discoverable (passkey) login ceremony against the store: it resolves the asserting user and registered credentials from the assertion's user handle, verifies the assertion response, and persists the post-login credential custody (sign count and authenticator flags, the cloned-authenticator detection state). It composes FinishLogin with a store-backed user finder; a consumer needing a custom finder or custody policy uses FinishLogin directly.
The custody write is best-effort: a store failure is logged at Warn and does not fail the login (sign-count bookkeeping is clone *detection*, not part of assertion verification). The returned user is the account as stored — the caller owns account-status policy and MUST check User.Enabled (and any app-specific state) before creating a session. A ceremony failure caused by a credential deleted server-side surfaces as a wrapped protocol.ErrorUnknownCredential, matchable with errors.As so callers can signal the client to forget the stale passkey.
func CredentialToAPI ¶
func CredentialToAPI(c *webauthn.Credential, userID int64, name string) *auth.PasskeyCredential
CredentialToAPI converts a webauthn.Credential to a PasskeyCredential.
func FinishLogin ¶
func FinishLogin(wa *webauthn.WebAuthn, sessionData *webauthn.SessionData, response *http.Request, userFinder func(rawID, userHandle []byte) (webauthn.User, error)) (webauthn.User, *webauthn.Credential, error)
FinishLogin completes a WebAuthn assertion ceremony (discoverable login).
func FinishRegistration ¶
func FinishRegistration(wa *webauthn.WebAuthn, user *User, sessionData *webauthn.SessionData, response *http.Request) (*webauthn.Credential, error)
FinishRegistration completes a WebAuthn registration ceremony.
func NewWebAuthn ¶
NewWebAuthn creates a configured webauthn.WebAuthn instance.
func PasskeyFriendlyName ¶
PasskeyFriendlyName returns a display-only, human-friendly label for a newly registered passkey, chosen so it does not duplicate any entry in existingNames (the user's current passkey labels). A known authenticator (matched by AAGUID) gets its bare registry name for the first of its kind (e.g. "Chrome on Mac") and a numbered name for each subsequent one ("Chrome on Mac 2", ...); an unknown authenticator is always numbered ("Passkey 1", "Passkey 2", ...). The numeric suffix is one past the highest already in use, so deleting a passkey that leaves a numbering gap never yields a duplicate label.
Types ¶
type AAGUIDEntry ¶
AAGUIDEntry maps an authenticator AAGUID to a friendly name.
type Store ¶
type Store interface {
GetPasskeysByUserID(ctx context.Context, userID int64) ([]auth.PasskeyCredential, error)
UpdatePasskeyAfterLogin(ctx context.Context, credID []byte, signCount uint32, flags auth.PasskeyFlags) error
GetUserByID(ctx context.Context, id int64) (*auth.User, error)
}
Store is the narrow store interface consumed by CompleteLogin: user and credential lookup to resolve the asserting account from its user handle, and the post-login credential-custody write. Any implementation of store.Composite satisfies it. Consumers composing the lower-level ceremony helpers (BeginLogin, FinishLogin) with their own user finder do not need it.
type User ¶
type User struct {
AuthUser *auth.User
Credentials []auth.PasskeyCredential
}
User adapts auth.User + credentials to the webauthn.User interface.
func NewWebAuthnUser ¶
NewWebAuthnUser returns a User with the given user and credentials.
func (*User) WebAuthnCredentials ¶
func (u *User) WebAuthnCredentials() []webauthn.Credential
WebAuthnCredentials converts the stored credentials to webauthn.Credential.
func (*User) WebAuthnDisplayName ¶
WebAuthnDisplayName returns the display name, falling back to username.
func (*User) WebAuthnID ¶
WebAuthnID encodes the user ID as a binary varint.