Skip to main content

AuthProvider

Trait AuthProvider 

Source
pub trait AuthProvider: Send + Sync {
    // Required method
    fn auth_header(&self) -> Option<AuthHeader<'_>>;
}
Expand description

Injects per-request authentication credentials.

Separate from transport configuration (TransportConfig) so any credential scheme can be paired with any transport.

Implement this trait when you need a custom Authorization header or other per-request credential scheme. For custom TLS/trust-root logic implement TransportConfig instead. NoneAuth, BearerAuth, and BasicAuth cover the common cases.

Implementations must not log the return value of auth_header; it contains credentials. The AuthHeader return type provides a compile-time guard against the most common leak path — its Debug impl redacts the value bytes — but the explicit expose_value accessor must not be fed into a tracing::* argument either.

§Intentional limitation: static single-header per-connection schemes (bd:JMAP-6r7c.20)

The trait shape commits the kit to “static, per-connection, single-header auth schemes” — bearer-token, HTTP Basic, mTLS via TransportConfig. Three constraints follow from the AuthHeader return type:

  1. One header per request. A scheme that needs to attach multiple headers per request (AWS SigV4 carries Authorization, X-Amz-Date, and X-Amz-Security-Token together) cannot be expressed by this trait.
  2. No per-request signature. auth_header takes &self only — there is no access to the request URL, method, or body. Schemes that compute an HMAC over the request body (SigV4, OAuth request signing) cannot be expressed.
  3. No async refresh. auth_header is sync. A scheme that needs to refresh an expired OAuth token before returning cannot await inside this method.

Workaround for callers who need any of the three: implement a custom TransportConfig that wires per-request middleware into the HttpClient it returns from build_client. The middleware can observe the full request, compute signatures, and refresh tokens asynchronously. The cost is the awkward layering inversion — TLS config and credential injection conceptually belong to different traits — but it does compose against the existing AuthProvider::auth_header trait without breakage.

A future reshape that supports the three constraints (likely a new trait, not a backward-compatible widening of this one) would not deprecate AuthProvider. The current trait stays as the “fast path for the common case” alongside any richer abstraction.

§Credential lifetime

Implementations that cache header bytes (e.g. BearerAuth, BasicAuth) SHOULD wrap the cached buffer in zeroize::Zeroizing or equivalent so the credential is overwritten on drop rather than left in freed heap until the allocator re-uses the slab. Callers that build a credential string before passing it into a constructor (e.g. BearerAuth::new(token)) SHOULD likewise store that string in a Zeroizing<String> — the zeroization done by the auth-type is bounded by what the type owns and cannot reach back into the caller’s buffer (bd:JMAP-6r7c.59).

Maintainer note (bd:JMAP-6lsm.19): if you add a new method to this trait, update BOTH manual blanket impls — Box<dyn AuthProvider> and Arc<dyn AuthProvider> — at the bottom of this file. The crate supports both Box and Arc trait-object call shapes (e.g. for sharing one credential source across multiple JmapClients), and a missing blanket method silently breaks one of those shapes without breaking the other.

Required Methods§

Source

fn auth_header(&self) -> Option<AuthHeader<'_>>

Return an optional AuthHeader to attach to every request.

Returns None when no Authorization header is required.

The header name and value both borrow from self and must live at least as long as the &self borrow. Implementations that pre-compute the values at construction time can return AuthHeader::new("authorization", &self.field) directly, avoiding any per-request allocation.

§Implementation contract

The returned strings must be valid HTTP field values (RFC 9110 §5):

  • Header name: lowercase ASCII token characters only (no spaces, no control characters); e.g. "authorization".
  • Header value: visible ASCII characters (0x21–0x7E) and horizontal tab (0x09) only; no other control characters.

Implementations that violate this contract will cause ClientError::InvalidArgument in connect_ws (ws/mod.rs), which parses the value into a typed http::HeaderValue. On HTTP code paths reqwest returns the error from .send() as a builder error rather than an InvalidArgument — the error type differs between the two paths. Test all custom AuthProvider implementations against both HTTP and WebSocket call paths.

Trait Implementations§

Source§

impl AuthProvider for Box<dyn AuthProvider>

Source§

fn auth_header(&self) -> Option<AuthHeader<'_>>

Return an optional AuthHeader to attach to every request. Read more

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl AuthProvider for Arc<dyn AuthProvider>

Source§

impl AuthProvider for Box<dyn AuthProvider>

Implementors§