pub trait PasskeyCredentialStore: Send + Sync {
// Required methods
fn put<'life0, 'life1, 'async_trait>(
&'life0 self,
cred: &'life1 Credential,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list_for_user<'life0, 'life1, 'async_trait>(
&'life0 self,
user_id: &'life1 UserId,
) -> Pin<Box<dyn Future<Output = Result<Vec<Credential>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
user_id: &'life1 UserId,
device_id: &'life2 DeviceId,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
cred: &'life1 Credential,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Origin-side multi-passkey-per-user persistence for the WebAuthn relying-party flow (P7 / R014).
Each row stores one passkey Credential (binding
DeviceBinding::Passkey, material
the serde_json-encoded webauthn-rs Passkey). The trait sits on
cheers-core’s Credential rather than webauthn-rs::Passkey so this
crate stays free of webauthn-rs in its public API — products bridge with
cheers::passkey::passkey_to_credential /
cheers::passkey::passkey_from_credential.
A user holds zero-or-more passkey credentials (phone, laptop, security key);
(user_id, device_id) is the unique key. Non-discoverable WebAuthn flow:
products call list_for_user to assemble the
allow_credentials set before start_authentication, and
update after a successful ceremony if the signature
counter advanced (see cheers::passkey::apply_authentication_result).
Long-lived credential material, indexed by user — belongs in the relational
SQL store (see cheers-sqlx), never in redis.
Required Methods§
Sourcefn put<'life0, 'life1, 'async_trait>(
&'life0 self,
cred: &'life1 Credential,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn put<'life0, 'life1, 'async_trait>(
&'life0 self,
cred: &'life1 Credential,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Insert a fresh passkey credential. The credential’s
user_id and device_id
fields are the unique key; StoreError::Conflict if the pair is
already taken.
Sourcefn list_for_user<'life0, 'life1, 'async_trait>(
&'life0 self,
user_id: &'life1 UserId,
) -> Pin<Box<dyn Future<Output = Result<Vec<Credential>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn list_for_user<'life0, 'life1, 'async_trait>(
&'life0 self,
user_id: &'life1 UserId,
) -> Pin<Box<dyn Future<Output = Result<Vec<Credential>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Every passkey credential owned by user_id. Order is unspecified.
Sourcefn delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
user_id: &'life1 UserId,
device_id: &'life2 DeviceId,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
user_id: &'life1 UserId,
device_id: &'life2 DeviceId,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Remove the passkey credential at (user_id, device_id).
StoreError::NotFound if no such row exists.
Sourcefn update<'life0, 'life1, 'async_trait>(
&'life0 self,
cred: &'life1 Credential,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
cred: &'life1 Credential,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Rewrite the stored material for the credential’s
(user_id, device_id) pair. Use after
apply_authentication_result to persist an advanced counter / updated
backup flags. StoreError::NotFound if the pair was never put.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".