Skip to main content

Crate passki

Crate passki 

Source
Expand description

Passki - A WebAuthn/Passkey implementation for Rust

Passki implements the server half of the WebAuthn protocol: the browser holds a private key and signs a challenge with it, this crate issues the challenge and verifies the response.

Registration and authentication are both two-step ceremonies. The first step returns a challenge to send to the browser plus a state value the second step needs; keep that state in a session or cache in between.

§Features

  • Support for multiple cryptographic algorithms (EdDSA/Ed25519, ES256/P-256, RS256/RSA)
  • Replay attack protection via signature counters
  • Flexible authenticator selection and user verification options
  • Credential exclusion to prevent duplicate registrations
  • Type-safe API with comprehensive error handling

§Example

use passki::{AuthenticationOptions, Passki, RegistrationOptions, StoredPasskey};

let passki = Passki::new(
    "example.com",              // relying party ID (the domain)
    &["https://example.com"],   // accepted origins
    "Example Corp"              // name shown in the browser prompt
);

// Registration step 1: issue a challenge
let user_id = b"unique_user_identifier_12345"; // at least 16 bytes
let (registration_challenge, registration_state) = passki.start_passkey_registration(
    user_id,
    "alice@example.com",            // username
    "Alice Smith",                  // display name
    RegistrationOptions::default(),
).expect("user_id must be at least 16 bytes");

// Send registration_challenge to the client as JSON, keep registration_state.

// Registration step 2: verify the credential the client created
let stored_passkey = passki.finish_passkey_registration(
    &registration_credential,
    &registration_state,
)?;

// Save stored_passkey in your database, associated with the user.

// Authentication step 1: issue a challenge
let (authentication_challenge, authentication_state) = passki.start_passkey_authentication(
    &user_passkeys,
    AuthenticationOptions::default(),
);

// Authentication step 2: verify the signature
let result = passki.finish_passkey_authentication(
    &authentication_credential,
    &authentication_state,
    &stored_passkey,
)?;

// Persist the new counter, or replay detection has nothing to compare against.
stored_passkey.counter = result.counter;

§Security Considerations

  • Serve over HTTPS; browsers refuse WebAuthn on insecure origins
  • Store the counter returned by each authentication to detect cloned authenticators
  • Public keys are not secret, but treat credential IDs as sensitive
  • Pass existing passkeys as exclusions so a user cannot register the same one twice
  • User IDs must be at least 16 bytes (a UUID or random bytes)

Structs§

AllowCredential
A credential the browser may use for this authentication.
AuthenticationChallenge
Challenge sent to the client to begin passkey authentication.
AuthenticationCredential
What the client sends back after navigator.credentials.get().
AuthenticationExtensions
Extensions included in an authentication challenge.
AuthenticationOptions
Options for starting a passkey authentication ceremony.
AuthenticationResult
Result of a successful authentication.
AuthenticationState
Server-side half of an authentication in progress.
AuthenticatorSelection
Constraints on which authenticators the browser may use for registration.
ClientData
The client data JSON the browser sent, parsed.
ClientExtensionResults
What credential.getClientExtensionResults() returned in the browser, one field per extension.
CredPropsResult
Credential properties returned by the browser after registration.
ExcludeCredential
An existing credential the authenticator must refuse to register again.
LargeBlobRegistrationInput
largeBlob extension input included in registration challenges.
LargeBlobResult
largeBlob extension result returned by the client.
Passki
Entry point of the crate: holds the relying party configuration and starts and finishes both ceremonies.
PrfEval
The inputs the authenticator derives its PRF outputs from.
PrfExtensionResult
prf extension result returned by the client.
PrfInput
prf extension input included in challenges.
PrfResults
The secrets the authenticator derived from the PRF inputs.
PubKeyCredParam
One signature algorithm the relying party will accept.
RegistrationChallenge
Challenge sent to the client to begin passkey registration.
RegistrationCredential
What the client sends back after navigator.credentials.create().
RegistrationExtensions
Extensions included in a registration challenge.
RegistrationOptions
Options for starting a passkey registration ceremony.
RegistrationState
Server-side half of a registration in progress.
RelyingParty
The site requesting authentication, as sent to the browser.
StoredPasskey
A registered passkey, as it should be saved in the database.
UserInfo
Information about the user account.

Enums§

AttestationConveyancePreference
How much the relying party wants to learn about the authenticator hardware at registration.
AttestationTrustPolicy
How strictly attestation certificate chains are checked, set together with the trust anchors by crate::Passki::with_attestation_trust.
AttestationType
What an attestation statement turned out to be worth.
AuthenticatorAttachment
Whether the authenticator is built into the device or a separate one.
AuthenticatorTransport
How an authenticator can be reached.
ClientDataType
The type of WebAuthn operation.
LargeBlobAuthenticationInput
largeBlob extension input included in authentication challenges.
LargeBlobSupport
How badly a relying party wants the new credential to support blob storage.
PasskiError
Error type for Passki operations.
ResidentKeyRequirement
Whether the authenticator should store the credential itself.
UserVerificationRequirement
Whether the user must prove who they are, with a PIN or biometric, rather than merely touching the authenticator.

Type Aliases§

Result
Convenience type alias for Results returned by Passki operations.