Providers
While exposing and implementing endpoints may be relatively straightforward, the real work is in implementing providers.
Providers are a set of Rust traits that allow the library to outsource data persistence, secure signing, and callback functionality. Each provider requires the library user to implement a corresponding trait, as defined below.
See Vercre's example verifier providers for more detail.
Verifier Metadata
The VerifierMetadata
provider is responsible for managing the OAuth 2.0 Client — or Verifier —
metadata on behalf of the library. In the case of Verifiable Presentation, the Verifier
is a client of the Authorization Server (the Wallet). The provider retrieves Client (Verifier)
metadata.
pub trait VerifierMetadata: Send + Sync {
fn metadata(&self, client_id: &str) -> impl Future<Output = Result<ClientMetadata>> + Send;
fn register(&self, verifier: &Verifier) -> impl Future<Output = Result<Verifier>> + Send;
}
Wallet Metadata
The WalletMetadata
provider is responsible for providing the library with information about the Authorization Server — or Wallet.
pub trait WalletMetadata: Send + Sync {
/// Returns the Authorization Server's metadata.
fn metadata(&self, wallet_id: &str) -> impl Future<Output = Result<Wallet>> + Send;
}
State Manager
As its name implies, StateStore
is responsible for temporarily storing and
managing state on behalf of the library.
pub trait StateStore: Send + Sync {
fn put(&self, key: &str, data: Vec<u8>, expiry: DateTime<Utc>,
) -> impl Future<Output = Result<()>> + Send;
fn get(&self, key: &str) -> impl Future<Output = Result<Vec<u8>>> + Send;
fn purge(&self, key: &str) -> impl Future<Output = Result<()>> + Send;
}
Data Security
KeyOps
provides the library with functionality for signing, encrypting, verifying and decrypting
data by implementing one of the supported signing and verification algorithms. Typically, implementers
will use a key vault, secure enclave, or HSM to manage private keys used for signing.
Supported algorithms are defined in the Credential Issuer metadata.
pub trait KeyOps: Send + Sync {
fn signer(&self, identifier: &str) -> anyhow::Result<impl Signer>;
fn verifier(&self, identifier: &str) -> anyhow::Result<impl Verifier>;
fn encryptor(&self, identifier: &str) -> anyhow::Result<impl Encryptor>;
fn decryptor(&self, identifier: &str) -> anyhow::Result<impl Decryptor>;
}
Signer
The Signer
trait provides the library with signing functionality for Verifiable Credential issuance.
pub trait Signer: Send + Sync {
fn algorithm(&self) -> Algorithm;
fn verification_method(&self) -> String;
fn sign(&self, msg: &[u8]) -> impl Future<Output = Vec<u8>> + Send {
let v = async { self.try_sign(msg).await.expect("should sign") };
v.into_future()
}
fn try_sign(&self, msg: &[u8]) -> impl Future<Output = anyhow::Result<Vec<u8>>> + Send;
}
Verifier
The Verifier
trait provides the library with signing verification functionality for Verifiable Credential issuance.
pub trait Verifier: Send + Sync {
fn deref_jwk(&self, did_url: &str)
-> impl Future<Output = anyhow::Result<PublicKeyJwk>> + Send;
}
Encryptor
The Encryptor
trait provides the library with encryption functionality for Verifiable Credential issuance.
pub trait Encryptor: Send + Sync {
fn encrypt(
&self, plaintext: &[u8], recipient_public_key: &[u8],
) -> impl Future<Output = anyhow::Result<Vec<u8>>> + Send;
fn public_key(&self) -> Vec<u8>;
}
Decryptor
The Decryptor
trait provides the library with decryption functionality for Verifiable Credential issuance.
pub trait Decryptor: Send + Sync {
fn decrypt(
&self, ciphertext: &[u8], sender_public_key: &[u8],
) -> impl Future<Output = anyhow::Result<Vec<u8>>> + Send;
}