11-25-2025 compliant Auth (#651)

* fix: correct discovery for AS metadata

* fix: add commitlint to dev container

* feat: add RFC 8707 support for resource parameter

* feat: pkce method verification

* feat(auth): implement SEP-835 scope handling and 403 upgrade flow

- add WWWAuthenticateParams for parsing scope and resource_metadata from headers
- add ScopeUpgradeConfig and scope tracking in AuthorizationManager
- add InsufficientScopeError and 403 handling in streamable HTTP client
- add scope union computation for progressive authorization
- export new public types: AuthClient, ScopeUpgradeConfig, WWWAuthenticateParams

Co-authored-by: fizy069 <fizy069@users.noreply.github.com>

* fix: reorg auth tests

* feat: add error to www-authenticate header parsing

* feat: consider protected resource metadata in scope selection

* fix: reorganize auth tests

* feat: add examples and docs for updated auth

---------

Co-authored-by: fizy069 <fizy069@users.noreply.github.com>
This commit is contained in:
Wils Dawson 2026-02-12 08:30:13 -08:00 • committed by GitHub
commit 61845d61c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -24,6 +24,24 @@ pub struct AuthRequiredError {
pub www_authenticate_header: String,
}
#[derive(Debug)]
pub struct InsufficientScopeError {
pub www_authenticate_header: String,
pub required_scope: Option<String>,
}
impl InsufficientScopeError {
/// check if scope upgrade is possible (i.e., we know what scope is required)
pub fn can_upgrade(&self) -> bool {
self.required_scope.is_some()
}
/// get the required scope for upgrade
pub fn get_required_scope(&self) -> Option<&str> {
self.required_scope.as_deref()
}
}
#[derive(Error, Debug)]
pub enum StreamableHttpError<E: std::error::Error + Send + Sync + 'static> {
#[error("SSE error: {0}")]
@ -56,6 +74,8 @@ pub enum StreamableHttpError<E: std::error::Error + Send + Sync + 'static> {
Auth(#[from] crate::transport::auth::AuthError),
#[error("Auth required")]
AuthRequired(AuthRequiredError),
#[error("Insufficient scope")]
InsufficientScope(InsufficientScopeError),
}
#[derive(Debug, Clone, Error)]