From 07c6065bdfe00fe0b778aabe2d6f1bb00aa61f0b Mon Sep 17 00:00:00 2001 From: Trezy Date: Mon, 11 May 2026 15:00:04 -0500 Subject: [PATCH] fix: dont block space creds on client key check Signed-off-by: Trezy --- src/xrpc/mod.rs | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/xrpc/mod.rs b/src/xrpc/mod.rs index 1865c15..ddf24b9 100644 --- a/src/xrpc/mod.rs +++ b/src/xrpc/mod.rs @@ -260,7 +260,19 @@ pub async fn xrpc_get( let mut params = parse_query_params(&raw_query); let claims = xrpc_claims.identity; - let rate_key = resolve_client_key(&state, claims.as_ref(), &parts, ¶ms)?; + // Space credential Bearer requests bypass the client-key requirement; + // rate-limit by the credential's sub DID instead. + let rate_key = if claims.is_none() { + if let Some(ref token) = xrpc_claims.space_credential { + crate::spaces::credential::peek_credential_sub(token).ok_or_else(|| { + AppError::Auth("invalid space credential: unable to extract sub".into()) + })? + } else { + resolve_client_key(&state, None, &parts, ¶ms)? + } + } else { + resolve_client_key(&state, claims.as_ref(), &parts, ¶ms)? + }; let lexicon = state.lexicons.get(&method).await; @@ -348,11 +360,23 @@ pub async fn xrpc_post( ) -> Result { let raw_query = raw_query.unwrap_or_default(); let mut params = parse_query_params(&raw_query); - let claims = xrpc_claims - .identity - .ok_or_else(|| AppError::Auth("XRPC procedures require DPoP authentication".into()))?; + let claims = xrpc_claims.identity; - let rate_key = resolve_client_key(&state, Some(&claims), &parts, ¶ms)?; + // Space credential Bearer requests bypass the client-key requirement; + // rate-limit by the credential's sub DID instead. + let rate_key = if claims.is_none() { + if let Some(ref token) = xrpc_claims.space_credential { + crate::spaces::credential::peek_credential_sub(token).ok_or_else(|| { + AppError::Auth("invalid space credential: unable to extract sub".into()) + })? + } else { + return Err(AppError::Auth( + "XRPC procedures require DPoP authentication".into(), + )); + } + } else { + resolve_client_key(&state, claims.as_ref(), &parts, ¶ms)? + }; let lexicon = state.lexicons.get(&method).await; @@ -416,6 +440,9 @@ pub async fn xrpc_post( coerce_params(&mut params, param_schema); } + let claims = claims + .ok_or_else(|| AppError::Auth("XRPC procedures require DPoP authentication".into()))?; + let mut response = procedure::handle_procedure(&state, &method, &claims, &body, ¶ms, &lexicon).await?; if let CheckResult::Allowed { -- 2.51.2