webauthnadapter

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package webauthnadapter implements the credbound.PasskeyProvider port on top of github.com/go-webauthn/webauthn. Every ceremony requires user verification, so passkey authentication yields AAL2 directly, and user handles are HMAC-derived from the account ID so authenticators never learn stable Credbound identifiers.

Wire it into credbound.Config.Passkeys:

passkeys, err := webauthnadapter.New(webauthnadapter.Config{
	RPID:          "example.com",
	RPDisplayName: "Example",
	RPOrigins:     []string{"https://app.example.com"},
	UserHandleKey: key, // at least 32 secret bytes
})

Credbound seals the ceremony session into its continuation; the host only shuttles the JSON options and browser responses.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// RPID is the relying-party identifier, normally the registrable
	// domain (e.g. "example.com"). Changing it invalidates every
	// registered passkey.
	RPID string
	// RPDisplayName is the human-readable relying-party name shown by
	// authenticators during ceremonies.
	RPDisplayName string
	// RPOrigins lists the exact web origins allowed to complete
	// ceremonies (e.g. "https://app.example.com"). Responses from any
	// other origin are rejected.
	RPOrigins []string
	// UserHandleKey is a secret of at least 32 bytes used to HMAC user IDs
	// into WebAuthn user handles. Keep it stable — rotating it orphans
	// discoverable credentials — and never reuse another Credbound key.
	UserHandleKey []byte
	// MaxCredentials caps how many stored passkeys one user may present in
	// a ceremony, 1 through 100. Zero defaults to 20.
	MaxCredentials int
}

Config identifies the WebAuthn relying party and the key material used to derive user handles.

type Provider

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

Provider runs WebAuthn registration and authentication ceremonies with mandatory user verification. It is safe for concurrent use and implements credbound.PasskeyProvider.

func New

func New(config Config) (*Provider, error)

New validates config and returns a Provider. A user handle key shorter than 32 bytes, an out-of-range credential cap or an invalid relying-party configuration is rejected.

func (*Provider) BeginAuthentication

func (p *Provider) BeginAuthentication(ctx context.Context, input credbound.PasskeyUser) (json.RawMessage, []byte, error)

BeginAuthentication starts an assertion ceremony over the user's stored passkeys and returns the browser request options plus the opaque session. It fails when the user has no passkey.

func (*Provider) BeginDecoyAuthentication

func (p *Provider) BeginDecoyAuthentication(ctx context.Context, seed []byte) (json.RawMessage, []byte, error)

BeginDecoyAuthentication fabricates a stable synthetic credential from the seed and runs the same assertion ceremony, so a caller cannot tell whether the address actually has a passkey. The seed is the manager's per-address digest; equal seeds yield an equal challenge shape across probes.

func (*Provider) BeginDiscoverableAuthentication

func (p *Provider) BeginDiscoverableAuthentication(ctx context.Context) (json.RawMessage, []byte, error)

BeginDiscoverableAuthentication starts a usernameless assertion ceremony: the request options carry an empty allowCredentials list and the authenticator offers its resident (discoverable) credentials, so no per-account challenge exists to enumerate.

func (*Provider) BeginRegistration

func (p *Provider) BeginRegistration(ctx context.Context, input credbound.PasskeyUser) (json.RawMessage, []byte, error)

BeginRegistration starts a passkey registration ceremony and returns the browser creation options plus the opaque session Credbound seals into the continuation.

func (*Provider) FinishAuthentication

func (p *Provider) FinishAuthentication(ctx context.Context, input credbound.PasskeyUser, rawSession, response []byte) ([]byte, []byte, error)

FinishAuthentication validates the browser's assertion response against the sealed session and returns the matched credential ID and its updated JSON encoding (sign counter, flags) for persistence via TouchPasskey.

func (*Provider) FinishDiscoverableAuthentication

func (p *Provider) FinishDiscoverableAuthentication(ctx context.Context, rawSession, response []byte, lookup credbound.PasskeyUserLookup) ([]byte, []byte, error)

FinishDiscoverableAuthentication validates the browser's assertion response, resolving the account through the lookup by the asserted credential ID and verifying the asserted user handle is the HMAC of that account's ID, so a tampered handle can never bind the assertion to a different user.

func (*Provider) FinishRegistration

func (p *Provider) FinishRegistration(ctx context.Context, input credbound.PasskeyUser, rawSession, response []byte) ([]byte, []byte, error)

FinishRegistration validates the browser's attestation response against the sealed session and returns the new credential ID and its JSON encoding for storage.

Jump to

Keyboard shortcuts

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