| Crates.io | passki |
| lib.rs | passki |
| version | 0.1.0 |
| created_at | 2026-01-25 12:39:57.157199+00 |
| updated_at | 2026-01-25 12:39:57.157199+00 |
| description | A simple and secure WebAuthn/Passkey authentication library |
| homepage | |
| repository | https://github.com/gblach/passki |
| max_upload_size | |
| id | 2068627 |
| size | 212,533 |
A simple, secure, and easy-to-use WebAuthn/Passkey implementation for Rust.
Add this to your Cargo.toml:
[dependencies]
passki = "0.1"
use passki::{
Passki, AttestationConveyancePreference, ResidentKeyRequirement,
UserVerificationRequirement, StoredPasskey,
};
// Initialize Passki with your relying party information
let passki = Passki::new(
"example.com", // Relying Party ID (domain)
"https://example.com", // Relying Party Origin
"Example Corp" // Relying Party Name
);
// Registration flow
// Step 1: Start registration and send challenge to client
let user_id = b"unique_user_identifier_12345"; // At least 16 bytes
let (registration_challenge, registration_state) = passki.start_passkey_registration(
user_id, // User ID (bytes)
"alice@example.com", // Username
"Alice Smith", // Display name
60000, // Timeout (ms)
AttestationConveyancePreference::None, // Attestation
ResidentKeyRequirement::Preferred, // Resident key
UserVerificationRequirement::Preferred, // User verification
None, // Exclude existing credentials
).expect("user_id must be at least 16 bytes");
// Send registration_challenge to client (as JSON)
// Client uses WebAuthn API to create credential
// Step 2: Receive credential from client and complete registration
let stored_passkey = passki.finish_passkey_registration(
®istration_credential, // Credential from client
®istration_state, // State from step 1
)?;
// Save stored_passkey to your database associated with the user
// Authentication flow
// Step 1: Start authentication and send challenge to client
let (authentication_challenge, authentication_state) = passki.start_passkey_authentication(
&user_passkeys, // User's stored passkeys
60000, // Timeout (ms)
UserVerificationRequirement::Preferred, // User verification
);
// Send authentication_challenge to client (as JSON)
// Client uses WebAuthn API to sign the challenge
// Step 2: Receive credential from client and verify authentication
let result = passki.finish_passkey_authentication(
&authentication_credential, // Credential from client
&authentication_state, // State from step 1
&stored_passkey, // User's passkey from database
)?;
// Update the counter in your database to prevent replay attacks
stored_passkey.counter = result.counter;
Passki supports the following COSE algorithms:
Passki follows a simple two-step pattern for both registration and authentication:
This design keeps state management simple and allows you to store session data however you prefer (in-memory, Redis, database, etc.).
Check out the examples/ directory for a complete working example:
poem.rs - Full integration with Poem web framework showing registration and authentication flowsRun the example:
cargo run --example poem
Then visit http://localhost:3000 in your browser.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0).
Passki is built on top of excellent Rust cryptography libraries: