klieo-auth-common 2.1.0

Shared authentication traits and types for klieo HTTP transports
Documentation
//! Server-side authentication port.

use crate::{AuthError, Headers, Identity};
use async_trait::async_trait;

/// Server-side authentication port.
///
/// Implementations validate the inbound credential and return the verified
/// [`Identity`] on success. Failures map to JSON-RPC `-32001
/// Unauthenticated` at the server layer.
#[async_trait]
pub trait Authenticator: Send + Sync {
    /// Validate the request's credentials and return the verified caller
    /// identity. `headers` is a protocol-agnostic view of the request
    /// headers; `payload` is the raw JSON-RPC request body (some
    /// authenticators sign over the body — most do not).
    async fn authenticate(
        &self,
        headers: &dyn Headers,
        payload: &[u8],
    ) -> Result<Identity, AuthError>;

    /// Returns `Err(AuthError::Rejected)` if `identity` is not
    /// authorised to invoke `method`. The default impl returns
    /// `Ok(())` so legacy authenticators without scope gating
    /// continue to compile without changes. Scope-gating impls (e.g.
    /// `klieo_auth_oauth::OAuthAuthenticator`) override this to enforce
    /// per-method allow-lists derived from token scopes.
    ///
    /// Called by the A2A and MCP dispatchers after `authenticate`
    /// succeeds and the JSON-RPC method name has been parsed, so a
    /// token with the wrong scope is rejected before the handler runs.
    async fn authorize_method(
        &self,
        _identity: &Identity,
        _method: &str,
    ) -> Result<(), AuthError> {
        Ok(())
    }

    /// Returns `true` if this authenticator accepts unauthenticated
    /// requests (no credential check). HTTP server wrappers refuse to
    /// bind a non-loopback address when this is `true` unless an
    /// explicit `allow_public_bind` opt-in is set.
    ///
    /// Defaults to `false`. Only
    /// [`AllowAnonymous`](crate::AllowAnonymous) overrides to `true`.
    fn allows_anonymous(&self) -> bool {
        false
    }
}