A library for ATProtocol identities.
1# atproto-xrpcs 2 3XRPC service framework for AT Protocol applications. 4 5## Overview 6 7Build AT Protocol services with JWT authorization, DID resolution, and cryptographic identity verification middleware. 8 9## Features 10 11- **JWT authorization**: Comprehensive JWT token validation with DID-based issuer verification 12- **DID resolution integration**: Automatic DID document resolution and key verification for authorization 13- **Identity verification**: Cryptographic verification of JWT signatures using DID documents 14- **Axum extractors**: Ready-to-use authorization extractors for Axum web handlers 15- **Structured errors**: Specialized error types for authorization and XRPC operations 16 17## CLI Tools 18 19This crate does not provide standalone CLI tools. It serves as a foundational library for building XRPC services. See `atproto-xrpcs-helloworld` for a complete example service implementation. 20 21## Usage 22 23### Basic XRPC Service 24 25```rust 26use atproto_xrpcs::authorization::Authorization; 27use axum::{Json, Router, extract::Query, routing::get}; 28use serde::Deserialize; 29use serde_json::json; 30 31#[derive(Deserialize)] 32struct HelloParams { 33 name: Option<String>, 34} 35 36async fn handle_hello( 37 params: Query<HelloParams>, 38 authorization: Option<Authorization>, 39) -> Json<serde_json::Value> { 40 let name = params.name.as_deref().unwrap_or("World"); 41 42 let message = if authorization.is_some() { 43 format!("Hello, authenticated {}!", name) 44 } else { 45 format!("Hello, {}!", name) 46 }; 47 48 Json(json!({ "message": message })) 49} 50 51let app = Router::new() 52 .route("/xrpc/com.example.hello", get(handle_hello)) 53 .with_state(your_web_context); 54``` 55 56### JWT Authorization 57 58```rust 59use atproto_xrpcs::authorization::Authorization; 60 61async fn handle_secure_endpoint( 62 authorization: Authorization, // Required authorization 63) -> Json<serde_json::Value> { 64 // The Authorization extractor automatically: 65 // 1. Validates the JWT token 66 // 2. Resolves the caller's DID document 67 // 3. Verifies the signature against the DID document 68 // 4. Provides access to caller identity information 69 70 let caller_did = authorization.subject(); 71 Json(json!({"caller": caller_did, "status": "authenticated"})) 72} 73``` 74 75### Error Handling 76 77```rust 78use atproto_xrpcs::errors::AuthorizationError; 79use axum::{response::IntoResponse, http::StatusCode}; 80 81async fn protected_handler( 82 authorization: Result<Authorization, AuthorizationError>, 83) -> impl IntoResponse { 84 match authorization { 85 Ok(auth) => (StatusCode::OK, "Access granted").into_response(), 86 Err(AuthorizationError::InvalidJWTFormat) => { 87 (StatusCode::UNAUTHORIZED, "Invalid token").into_response() 88 } 89 Err(AuthorizationError::SubjectResolutionFailed { .. }) => { 90 (StatusCode::FORBIDDEN, "Identity verification failed").into_response() 91 } 92 Err(_) => { 93 (StatusCode::INTERNAL_SERVER_ERROR, "Authorization error").into_response() 94 } 95 } 96} 97``` 98 99## Authorization Flow 100 101The `Authorization` extractor implements: 102 1031. JWT extraction from HTTP Authorization headers 1042. Token validation (signature and claims structure) 1053. DID resolution for the token issuer 1064. Signature verification against DID document public keys 1075. Identity confirmation and authorization scope validation 108 109## License 110 111MIT License