Skip to main content

mcp_kit/auth/
provider.rs

1use std::{future::Future, pin::Pin, sync::Arc};
2
3use crate::{
4    auth::{credentials::Credentials, identity::AuthenticatedIdentity},
5    error::McpResult,
6};
7
8/// A pinned, boxed future returned by [`AuthProvider::authenticate`].
9pub type AuthFuture<'a> =
10    Pin<Box<dyn Future<Output = McpResult<AuthenticatedIdentity>> + Send + 'a>>;
11
12/// Validates raw [`Credentials`] and produces an [`AuthenticatedIdentity`], or
13/// returns [`McpError::Unauthorized`] on failure.
14///
15/// The trait is object-safe so providers can be stored as `Arc<dyn AuthProvider>`
16/// (see [`DynAuthProvider`]).
17///
18/// # Implementing your own provider
19///
20/// ```rust,no_run
21/// use mcp_kit::auth::{AuthProvider, AuthFuture, Credentials, AuthenticatedIdentity};
22/// use mcp_kit::McpResult;
23///
24/// struct MyProvider;
25///
26/// impl AuthProvider for MyProvider {
27///     fn authenticate<'a>(&'a self, creds: &'a Credentials) -> AuthFuture<'a> {
28///         Box::pin(async move {
29///             match creds {
30///                 Credentials::Bearer { token } if token == "secret" => {
31///                     Ok(AuthenticatedIdentity::new("user"))
32///                 }
33///                 _ => Err(mcp_kit::McpError::Unauthorized("invalid token".into())),
34///             }
35///         })
36///     }
37///
38///     fn accepts(&self, creds: &Credentials) -> bool {
39///         matches!(creds, Credentials::Bearer { .. })
40///     }
41/// }
42/// ```
43///
44/// [`McpError::Unauthorized`]: crate::error::McpError::Unauthorized
45pub trait AuthProvider: Send + Sync + 'static {
46    /// Validate `credentials` and return the authenticated identity, or an error.
47    fn authenticate<'a>(&'a self, credentials: &'a Credentials) -> AuthFuture<'a>;
48
49    /// Returns `true` if this provider knows how to handle the given credential
50    /// variant. Used by [`CompositeAuthProvider`] to select the right delegate
51    /// without unnecessarily calling `authenticate`.
52    ///
53    /// [`CompositeAuthProvider`]: crate::auth::composite::CompositeAuthProvider
54    fn accepts(&self, credentials: &Credentials) -> bool;
55}
56
57/// A type-erased, cheaply cloneable auth provider.
58pub type DynAuthProvider = Arc<dyn AuthProvider>;