passkey

package
v2.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: BSD-3-Clause Imports: 33 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrPasskeyServiceUnavailable = errors.Sentinel("passkey service is unavailable")
	ErrPasskeyCeremony           = errors.Sentinel("invalid or expired passkey ceremony")
	ErrPasskeyTransaction        = errors.Sentinel("invalid or expired authentication transaction")
	ErrPasskeyResponse           = errors.Sentinel("invalid passkey response")
	ErrPasskeyNotFound           = errors.Sentinel("passkey not found")
	ErrPasskeyExists             = errors.Sentinel("passkey already registered")
	ErrPasskeyStepUpRequired     = errors.Sentinel("fresh step-up authentication is required")
	ErrPasskeyMFAEnabled         = errors.Sentinel("passkey MFA must be disabled first")
	ErrPasskeyMFAAlreadyEnabled  = errors.Sentinel("passkey MFA is already enabled")
	ErrPasskeyMFANotEnabled      = errors.Sentinel("passkey MFA is not enabled")
	ErrPasskeyNoCredential       = errors.Sentinel("no passkeys are registered")
	ErrPasskeyLastCredential     = errors.Sentinel("cannot remove the last usable authentication method")
	ErrPasskeyRecoveryCode       = errors.Sentinel("invalid recovery code")
	ErrPasskeyName               = errors.Sentinel("invalid passkey name")
)

Functions

func RegisterPasskeys

func RegisterPasskeys(api huma.API, passkeyService *PasskeyService, authService *auth.AuthService, userService *user.UserService)

Types

type AuthenticationCompletion

type AuthenticationCompletion struct {
	User   *models.User
	Meta   auth.SessionMeta
	Source string
}

AuthenticationCompletion carries the original primary-auth metadata across an MFA transaction so the eventual session cannot be assigned client-chosen source or network metadata.

type BeginPasskeyRegistrationInput

type BeginPasskeyRegistrationInput struct {
	StepUpToken string `header:"X-Step-Up-Token"`
}

type BeginPasskeyRegistrationOutput

type BeginPasskeyRegistrationOutput struct {
	Body base.ApiResponse[passkeyBeginResponse]
}

type BeginStepUpInput

type BeginStepUpInput struct{}

type BeginStepUpOutput

type BeginStepUpOutput struct {
	Body base.ApiResponse[passkeyBeginResponse]
}

type DeletePasskeyInput

type DeletePasskeyInput struct {
	ID          string `path:"id"`
	StepUpToken string `header:"X-Step-Up-Token"`
}

type DeletePasskeyOutput

type DeletePasskeyOutput struct {
	Body base.ApiResponse[base.MessageResponse]
}

type FinishPasskeyRegistrationInput

type FinishPasskeyRegistrationInput struct {
	UserAgent string `header:"User-Agent"`
	Body      passkeyCredentialBody
}

type FinishPasskeyRegistrationOutput

type FinishPasskeyRegistrationOutput struct {
	Body base.ApiResponse[PasskeySummary]
}

type FinishStepUpInput

type FinishStepUpInput struct {
	Body stepUpFinishBody
}

type FinishStepUpOutput

type FinishStepUpOutput struct {
	Body base.ApiResponse[StepUpGrant]
}

type GetMFAStatusOutput

type GetMFAStatusOutput struct {
	Body base.ApiResponse[MFAStatus]
}

type GetPasskeyCapabilitiesOutput

type GetPasskeyCapabilitiesOutput struct {
	Body base.ApiResponse[PasskeyCapabilities]
}

type ListMyPasskeysOutput

type ListMyPasskeysOutput struct {
	Body base.ApiResponse[[]PasskeySummary]
}

type MFARecoveryCodesOutput

type MFARecoveryCodesOutput struct {
	Body base.ApiResponse[RecoveryCodesResponse]
}

type MFASettingsInput

type MFASettingsInput struct {
	StepUpToken string `header:"X-Step-Up-Token"`
}

type MFAStatus

type MFAStatus struct {
	Enabled                bool `json:"enabled"`
	PasskeyCount           int  `json:"passkeyCount"`
	RecoveryCodesRemaining int  `json:"recoveryCodesRemaining"`
}

MFAStatus is the account's passkey MFA state. Recovery codes are counted, but their plaintext values are never returned after generation.

type MobilePasskeyExchangeInput

type MobilePasskeyExchangeInput struct {
	UserAgent string `header:"User-Agent"`
	Body      mobilePasskeyExchangeBody
}

type MobilePasskeyExchangeOutput

type MobilePasskeyExchangeOutput struct {
	SetCookie []string `header:"Set-Cookie" doc:"Session cookie"`
	Body      base.ApiResponse[authtypes.AuthenticationResponse]
}

type MobilePasskeyFinishInput

type MobilePasskeyFinishInput struct {
	Body mobilePasskeyFinishBody
}

type MobilePasskeyFinishOutput

type MobilePasskeyFinishOutput struct {
	Body base.ApiResponse[authtypes.MobilePasskeyCompletion]
}

type PasskeyCapabilities

type PasskeyCapabilities struct {
	PasskeyMFAEnabled          bool `json:"passkeyMfaEnabled"`
	PasskeyCount               int  `json:"passkeyCount"`
	HasLocalPassword           bool `json:"hasLocalPassword"`
	HasOIDCFallback            bool `json:"hasOidcFallback"`
	CanEnrollWithActiveSession bool `json:"canEnrollWithActiveSession"`
	CanDeleteLastPasskey       bool `json:"canDeleteLastPasskey"`
	RequiresStepUp             bool `json:"requiresStepUp"`
}

PasskeyCapabilities describes the server-derived authentication choices for the current account. It deliberately does not trust client-supplied flags.

type PasskeyChallenge

type PasskeyChallenge struct {
	CeremonyID    string
	TransactionID string
	Options       any
	ExpiresAt     time.Time
}

PasskeyChallenge is the public result of a WebAuthn ceremony begin. The matching SessionData remains in passkey_ceremonies.

type PasskeyHandler

type PasskeyHandler struct {
	// contains filtered or unexported fields
}

func (*PasskeyHandler) BeginMFA

func (*PasskeyHandler) BeginPasskeyLogin

func (h *PasskeyHandler) BeginPasskeyLogin(ctx context.Context, _ *struct{}) (*PasskeyLoginBeginOutput, error)

func (*PasskeyHandler) BeginRegistration

func (*PasskeyHandler) BeginStepUp

func (*PasskeyHandler) DeletePasskey

func (h *PasskeyHandler) DeletePasskey(ctx context.Context, input *DeletePasskeyInput) (*DeletePasskeyOutput, error)

func (*PasskeyHandler) DisableMFA

func (*PasskeyHandler) EnableMFA

func (*PasskeyHandler) ExchangeMobilePasskeyLogin

func (h *PasskeyHandler) ExchangeMobilePasskeyLogin(ctx context.Context, input *MobilePasskeyExchangeInput) (*MobilePasskeyExchangeOutput, error)

func (*PasskeyHandler) FinishMFA

func (*PasskeyHandler) FinishMobilePasskeyLogin

func (h *PasskeyHandler) FinishMobilePasskeyLogin(ctx context.Context, input *MobilePasskeyFinishInput) (*MobilePasskeyFinishOutput, error)

func (*PasskeyHandler) FinishPasskeyLogin

func (*PasskeyHandler) FinishRegistration

func (*PasskeyHandler) FinishStepUp

func (h *PasskeyHandler) FinishStepUp(ctx context.Context, input *FinishStepUpInput) (*FinishStepUpOutput, error)

func (*PasskeyHandler) GetCapabilities

func (h *PasskeyHandler) GetCapabilities(ctx context.Context, _ *struct{}) (*GetPasskeyCapabilitiesOutput, error)

func (*PasskeyHandler) GetMFAStatus

func (h *PasskeyHandler) GetMFAStatus(ctx context.Context, _ *struct{}) (*GetMFAStatusOutput, error)

func (*PasskeyHandler) ListMyPasskeys

func (h *PasskeyHandler) ListMyPasskeys(ctx context.Context, _ *struct{}) (*ListMyPasskeysOutput, error)

func (*PasskeyHandler) PasswordStepUp

func (h *PasskeyHandler) PasswordStepUp(ctx context.Context, input *PasswordStepUpInput) (*PasswordStepUpOutput, error)

func (*PasskeyHandler) RegenerateRecoveryCodes

func (h *PasskeyHandler) RegenerateRecoveryCodes(ctx context.Context, input *MFASettingsInput) (*MFARecoveryCodesOutput, error)

func (*PasskeyHandler) RenamePasskey

func (h *PasskeyHandler) RenamePasskey(ctx context.Context, input *RenamePasskeyInput) (*RenamePasskeyOutput, error)

func (*PasskeyHandler) UseRecoveryCode

func (h *PasskeyHandler) UseRecoveryCode(ctx context.Context, input *PasskeyRecoveryInput) (*PasskeyRecoveryOutput, error)

type PasskeyLoginBeginOutput

type PasskeyLoginBeginOutput struct {
	Body base.ApiResponse[passkeyBeginResponse]
}

type PasskeyLoginFinishInput

type PasskeyLoginFinishInput struct {
	UserAgent string `header:"User-Agent"`
	Body      passkeyCredentialBody
}

type PasskeyLoginFinishOutput

type PasskeyLoginFinishOutput struct {
	SetCookie []string `header:"Set-Cookie" doc:"Session cookie"`
	Body      base.ApiResponse[authtypes.AuthenticationResponse]
}

type PasskeyMFAFinishInput

type PasskeyMFAFinishInput struct {
	Body mfaFinishBody
}

type PasskeyMFAFinishOutput

type PasskeyMFAFinishOutput struct {
	SetCookie []string `header:"Set-Cookie" doc:"Session cookie"`
	Body      base.ApiResponse[authtypes.AuthenticationResponse]
}

type PasskeyMFAStartInput

type PasskeyMFAStartInput struct {
	Body mfaBeginBody
}

type PasskeyMFAStartOutput

type PasskeyMFAStartOutput struct {
	Body base.ApiResponse[authtypes.MFAChallenge]
}

type PasskeyRecoveryInput

type PasskeyRecoveryInput struct {
	Body recoveryBody
}

type PasskeyRecoveryOutput

type PasskeyRecoveryOutput struct {
	SetCookie []string `header:"Set-Cookie" doc:"Session cookie"`
	Body      base.ApiResponse[authtypes.AuthenticationResponse]
}

type PasskeyService

type PasskeyService = passkeyService

PasskeyService owns WebAuthn ceremonies, passkey persistence, MFA transactions, recovery codes, and step-up grants. It intentionally does not issue JWTs; auth.AuthService remains the single token/session issuer.

func NewPasskeyService

func NewPasskeyService(db *database.DB, cfg *config.Config) *PasskeyService

type PasskeySummary

type PasskeySummary struct {
	ID                      string     `json:"id"`
	Name                    string     `json:"name"`
	RPID                    string     `json:"rpId"`
	AAGUID                  string     `json:"aaguid,omitempty"`
	Transports              []string   `json:"transports,omitempty"`
	BackupEligible          bool       `json:"backupEligible"`
	BackupState             bool       `json:"backupState"`
	CloneWarning            bool       `json:"cloneWarning"`
	AuthenticatorAttachment string     `json:"authenticatorAttachment,omitempty"`
	CreatedAt               time.Time  `json:"createdAt"`
	UpdatedAt               *time.Time `json:"updatedAt,omitempty"`
	LastUsedAt              *time.Time `json:"lastUsedAt,omitempty"`
}

PasskeySummary is the safe representation of a stored credential.

type PasswordStepUpInput

type PasswordStepUpInput struct {
	Body passwordReauthBody
}

type PasswordStepUpOutput

type PasswordStepUpOutput struct {
	Body base.ApiResponse[StepUpGrant]
}

type RecoveryCodesResponse

type RecoveryCodesResponse struct {
	Codes []string `json:"codes" doc:"Recovery codes; shown only once"`
}

type RenamePasskeyInput

type RenamePasskeyInput struct {
	ID          string `path:"id"`
	StepUpToken string `header:"X-Step-Up-Token"`
	Body        renamePasskeyBody
}

type RenamePasskeyOutput

type RenamePasskeyOutput struct {
	Body base.ApiResponse[PasskeySummary]
}

type StepUpGrant

type StepUpGrant struct {
	Token     string    `json:"token"`
	ExpiresAt time.Time `json:"expiresAt"`
}

StepUpGrant is returned after a fresh password or passkey assertion. The token is hashed in the database and stays usable, for the issuing session only, until ExpiresAt.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL