A library for ATProtocol identities.

migration notice

+2 -350
+2 -350
README.md
··· 1 - # AT Protocol Identity Rust Components 2 - 3 - A comprehensive collection of Rust components for creating AT Protocol applications. This workspace provides essential building blocks for content-addressed data, identity management, repository operations, record signing, OAuth 2.0 authentication flows, HTTP client operations, XRPC services, and real-time event streaming. 4 - 5 - **Origin**: Parts of this project were extracted from the open-source [smokesignal.events](https://tangled.sh/@smokesignal.events/smokesignal) project, an AT Protocol event and RSVP management application. This library is released under the MIT license to enable broader AT Protocol ecosystem development. 6 - 7 - ## Components 8 - 9 - This workspace contains 15 specialized crates that work together to provide complete AT Protocol application development capabilities: 10 - 11 - ### Data Foundations 12 - 13 - - **[`atproto-dasl`](crates/atproto-dasl/)** - DASL (Data-Addressed Structures & Links) framework implementing CID computation, DRISL (deterministic DAG-CBOR encoding), CAR v1 archives, block storage backends, RASL retrieval, BDASL large file hashing, and Web Tiles. *Includes 1 CLI tool.* 14 - 15 - ### Identity & Cryptography 16 - 17 - - **[`atproto-identity`](crates/atproto-identity/)** - Core identity management with multi-method DID resolution (plc, web, key), DNS/HTTP handle resolution, PLC directory operations, and P-256/P-384/K-256 cryptographic operations. *Includes 6 CLI tools.* 18 - - **[`atproto-attestation`](crates/atproto-attestation/)** - CID-first attestation utilities for creating and verifying cryptographic signatures on AT Protocol records, supporting both inline and remote attestation workflows. *Includes 2 CLI tools.* 19 - - **[`atproto-record`](crates/atproto-record/)** - Record utilities including TID generation, AT-URI parsing, datetime formatting, and CID generation using IPLD DAG-CBOR serialization. *Includes 1 CLI tool.* 20 - - **[`atproto-lexicon`](crates/atproto-lexicon/)** - Lexicon schema resolution and validation for AT Protocol, supporting recursive resolution, NSID validation, and DNS-based lexicon discovery. *Includes 1 CLI tool.* 21 - 22 - ### Repository 23 - 24 - - **[`atproto-repo`](crates/atproto-repo/)** - AT Protocol repository handling with Merkle Search Tree (MST) encoding/decoding, commit structures, tree diffing for sync, and configurable verification. Builds on `atproto-dasl` for CAR and storage. *Includes 2 CLI tools.* 25 - 26 - ### Authentication & Authorization 27 - 28 - - **[`atproto-oauth`](crates/atproto-oauth/)** - Complete OAuth 2.0 implementation with AT Protocol security extensions including DPoP (RFC 9449), PKCE (RFC 7636), JWT operations, and secure storage abstractions. *Includes 1 CLI tool.* 29 - - **[`atproto-oauth-aip`](crates/atproto-oauth-aip/)** - OAuth AIP (Identity Provider) implementation providing complete authorization code flow with PAR, token exchange, and AT Protocol session management. 30 - - **[`atproto-oauth-axum`](crates/atproto-oauth-axum/)** - Production-ready Axum web handlers for OAuth endpoints including authorization callbacks, JWKS endpoints, and client metadata. *Includes 1 CLI tool.* 31 - 32 - ### Client & Service Development 33 - 34 - - **[`atproto-client`](crates/atproto-client/)** - HTTP client library supporting multiple authentication methods (DPoP, Bearer tokens, sessions) with native XRPC protocol operations and repository management. *Includes 4 CLI tools.* 35 - - **[`atproto-xrpcs`](crates/atproto-xrpcs/)** - XRPC service framework providing JWT authorization extractors, DID resolution integration, and Axum middleware for building AT Protocol services. 36 - - **[`atproto-xrpcs-helloworld`](crates/atproto-xrpcs-helloworld/)** - Complete example XRPC service demonstrating DID:web identity, service document generation, and JWT authentication patterns. *Includes 1 service binary.* 37 - 38 - ### Real-time Event Processing 39 - 40 - - **[`atproto-jetstream`](crates/atproto-jetstream/)** - WebSocket consumer for AT Protocol Jetstream events with Zstandard compression, automatic reconnection, and configurable event filtering. *Includes 1 CLI tool.* 41 - - **[`atproto-tap`](crates/atproto-tap/)** - TAP (Trusted Attestation Protocol) service consumer for filtered, verified AT Protocol repository events with MST integrity checks, automatic backfill, and acknowledgment-based delivery. *Includes 2 CLI tools.* 42 - 43 - ### Utilities 44 - 45 - - **[`atproto-extras`](crates/atproto-extras/)** - Facet parsing and rich text utilities for AT Protocol, extracting mentions, URLs, and hashtags from plain text with correct UTF-8 byte offset calculation. *Includes 1 CLI tool.* 46 - 47 - ## Quick Start 48 - 49 - Add the crates to your `Cargo.toml`: 50 - 51 - ```toml 52 - [dependencies] 53 - atproto-dasl = "0.13.0" 54 - atproto-identity = "0.13.0" 55 - atproto-attestation = "0.13.0" 56 - atproto-record = "0.13.0" 57 - atproto-repo = "0.13.0" 58 - atproto-lexicon = "0.13.0" 59 - atproto-oauth = "0.13.0" 60 - atproto-oauth-aip = "0.13.0" 61 - atproto-client = "0.13.0" 62 - atproto-extras = "0.13.0" 63 - atproto-tap = "0.13.0" 64 - # Add others as needed 65 - ``` 66 - 67 - ### Basic Identity Resolution 68 - 69 - ```rust 70 - use atproto_identity::resolve::{resolve_subject, create_resolver}; 71 - 72 - #[tokio::main] 73 - async fn main() -> anyhow::Result<()> { 74 - let http_client = reqwest::Client::new(); 75 - let dns_resolver = create_resolver(&[]); 76 - 77 - let did = resolve_subject(&http_client, &dns_resolver, "alice.bsky.social").await?; 78 - println!("Resolved DID: {}", did); 79 - 80 - Ok(()) 81 - } 82 - ``` 83 - 84 - ### Lexicon Resolution 85 - 86 - ```rust 87 - use atproto_lexicon::resolve::{DefaultLexiconResolver, LexiconResolver}; 88 - use atproto_identity::resolve::HickoryDnsResolver; 89 - 90 - #[tokio::main] 91 - async fn main() -> anyhow::Result<()> { 92 - let http_client = reqwest::Client::new(); 93 - let dns_resolver = HickoryDnsResolver::create_resolver(&[]); 94 - let resolver = DefaultLexiconResolver::new(http_client, dns_resolver); 95 - 96 - // Resolve a lexicon schema 97 - let lexicon = resolver.resolve("app.bsky.feed.post").await?; 98 - println!("Lexicon schema: {}", serde_json::to_string_pretty(&lexicon)?); 99 - 100 - Ok(()) 101 - } 102 - ``` 103 - 104 - ### Record Signing 105 - 106 - ```rust 107 - use atproto_attestation::{create_inline_attestation, AnyInput}; 108 - use atproto_identity::key::{generate_key, KeyType}; 109 - use serde_json::json; 110 - 111 - fn main() -> anyhow::Result<()> { 112 - let key = generate_key(KeyType::P256Private)?; 113 - 114 - let record = json!({ 115 - "$type": "app.bsky.feed.post", 116 - "text": "Hello AT Protocol!", 117 - "createdAt": "2024-01-01T00:00:00.000Z" 118 - }); 119 - 120 - let metadata = json!({ 121 - "$type": "com.example.inlineSignature", 122 - "key": "did:key:...", 123 - "issuer": "did:plc:issuer123", 124 - "issuedAt": "2024-01-01T00:00:00.000Z" 125 - }); 126 - 127 - let signed_record = create_inline_attestation( 128 - AnyInput::Serialize(record), 129 - AnyInput::Serialize(metadata), 130 - "did:plc:repo123", 131 - &key 132 - )?; 133 - 134 - println!("Signed record: {}", serde_json::to_string_pretty(&signed_record)?); 135 - Ok(()) 136 - } 137 - ``` 138 - 139 - ### XRPC Service 140 - 141 - ```rust 142 - use atproto_xrpcs::authorization::Authorization; 143 - use axum::{Json, Router, extract::Query, routing::get}; 144 - use serde::Deserialize; 145 - use serde_json::json; 146 - 147 - #[derive(Deserialize)] 148 - struct HelloParams { 149 - subject: Option<String>, 150 - } 151 - 152 - async fn handle_hello( 153 - params: Query<HelloParams>, 154 - authorization: Option<Authorization>, 155 - ) -> Json<serde_json::Value> { 156 - let subject = params.subject.as_deref().unwrap_or("World"); 157 - 158 - let message = if let Some(auth) = authorization { 159 - format!("Hello, authenticated {}! (caller: {})", subject, auth.subject()) 160 - } else { 161 - format!("Hello, {}!", subject) 162 - }; 163 - 164 - Json(json!({ "message": message })) 165 - } 166 - 167 - #[tokio::main] 168 - async fn main() -> anyhow::Result<()> { 169 - let app = Router::new() 170 - .route("/xrpc/com.example.hello", get(handle_hello)) 171 - .with_state(your_web_context); 172 - 173 - let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?; 174 - axum::serve(listener, app).await?; 175 - 176 - Ok(()) 177 - } 178 - ``` 179 - 180 - ### OAuth Client Flow 181 - 182 - ```rust 183 - use atproto_oauth_aip::workflow::{oauth_init, oauth_complete, session_exchange, OAuthClient}; 184 - use atproto_oauth::workflow::OAuthRequestState; 185 - 186 - #[tokio::main] 187 - async fn main() -> anyhow::Result<()> { 188 - let http_client = reqwest::Client::new(); 189 - 190 - let oauth_client = OAuthClient { 191 - redirect_uri: "https://your-app.com/callback".to_string(), 192 - client_id: "your-client-id".to_string(), 193 - client_secret: "your-client-secret".to_string(), 194 - }; 195 - 196 - let oauth_request_state = OAuthRequestState { 197 - state: "random-state".to_string(), 198 - nonce: "random-nonce".to_string(), 199 - code_challenge: "code-challenge".to_string(), 200 - scope: "atproto transition:generic".to_string(), 201 - }; 202 - 203 - // 1. Start OAuth flow with Pushed Authorization Request 204 - let par_response = oauth_init( 205 - &http_client, 206 - &oauth_client, 207 - Some("alice.bsky.social"), 208 - "https://auth-server.example.com/par", 209 - &oauth_request_state, 210 - ).await?; 211 - 212 - println!("PAR request URI: {}", par_response.request_uri); 213 - 214 - // 2. After user authorizes and returns with a code, exchange it for tokens 215 - let token_response = oauth_complete( 216 - &http_client, 217 - &oauth_client, 218 - "https://auth-server.example.com/token", 219 - "received-auth-code", 220 - &oauth_request, // OAuthRequest from your stored state 221 - ).await?; 222 - 223 - // 3. Exchange token for AT Protocol session 224 - let session = session_exchange( 225 - &http_client, 226 - "https://pds.example.com", 227 - &token_response.access_token, 228 - ).await?; 229 - 230 - println!("Authenticated as: {} ({})", session.handle, session.did); 231 - 232 - Ok(()) 233 - } 234 - ``` 235 - 236 - ## Command Line Tools 237 - 238 - The workspace includes 23 command-line tools across 11 crates, providing ready-to-use utilities for AT Protocol development and testing. Most CLI tools require the `clap` feature: 239 - 240 - ```bash 241 - # Build with CLI support 242 - cargo build --features clap --bins 243 - 244 - # DASL operations (atproto-dasl crate) 245 - cargo run --package atproto-dasl --features clap --bin atproto-dasl -- --help 246 - 247 - # Identity operations (atproto-identity crate) 248 - cargo run --features clap,hickory-dns --bin atproto-identity-resolve -- alice.bsky.social 249 - cargo run --features clap --bin atproto-identity-key -- generate p256 250 - cargo run --features clap --bin atproto-identity-sign -- did:key:... data.json 251 - cargo run --features clap --bin atproto-identity-validate -- did:key:... data.json signature 252 - cargo run --features clap,hickory-dns --bin atproto-identity-plc-audit -- did:plc:... 253 - cargo run --features clap,hickory-dns --bin atproto-identity-plc-fork-viz -- did:plc:... 254 - 255 - # Attestation operations (atproto-attestation crate) 256 - cargo run --package atproto-attestation --features clap,tokio --bin atproto-attestation-sign -- inline record.json did:key:... metadata.json 257 - cargo run --package atproto-attestation --features clap,tokio --bin atproto-attestation-verify -- signed_record.json 258 - 259 - # Record operations (atproto-record crate) 260 - cat record.json | cargo run --features clap --bin atproto-record-cid 261 - 262 - # Repository operations (atproto-repo crate) 263 - cargo run --package atproto-repo --features clap --bin atproto-repo-car -- ls repo.car 264 - cargo run --package atproto-repo --features clap --bin atproto-repo-mst -- ls repo.car 265 - 266 - # Lexicon operations (atproto-lexicon crate) 267 - cargo run --features clap,hickory-dns --bin atproto-lexicon-resolve -- app.bsky.feed.post 268 - 269 - # Client operations (atproto-client crate) 270 - cargo run --features clap --bin atproto-client-auth -- login alice.bsky.social password123 271 - cargo run --features clap --bin atproto-client-app-password -- alice.bsky.social access_token /xrpc/com.atproto.repo.listRecords 272 - cargo run --features clap --bin atproto-client-dpop -- alice.bsky.social did:key:... access_token /xrpc/com.atproto.repo.listRecords 273 - cargo run --features clap --bin atproto-client-put-record -- --help 274 - 275 - # OAuth operations (atproto-oauth crate) 276 - cargo run --package atproto-oauth --features clap --bin atproto-oauth-service-token -- --help 277 - 278 - # OAuth operations (atproto-oauth-axum crate) 279 - cargo run --package atproto-oauth-axum --features clap --bin atproto-oauth-tool -- login did:key:... alice.bsky.social 280 - 281 - # XRPC service (atproto-xrpcs-helloworld crate) 282 - cargo run --bin atproto-xrpcs-helloworld 283 - 284 - # Event streaming (atproto-jetstream crate) 285 - cargo run --features clap --bin atproto-jetstream-consumer -- jetstream1.us-east.bsky.network dictionary.zstd 286 - 287 - # TAP service consumer (atproto-tap crate) 288 - cargo run --package atproto-tap --features clap --bin atproto-tap-client -- --help 289 - cargo run --package atproto-tap --features clap --bin atproto-tap-extras -- --help 290 - 291 - # Rich text utilities (atproto-extras crate) 292 - cargo run --package atproto-extras --features clap,cli,hickory-dns --bin atproto-extras-parse-facets -- "Hello @alice.bsky.social" 293 - ``` 294 - 295 - ## Development 296 - 297 - ```bash 298 - # Build all crates 299 - cargo build 300 - 301 - # Run all tests 302 - cargo test 303 - 304 - # Format and lint 305 - cargo fmt && cargo clippy 306 - 307 - # Generate documentation 308 - cargo doc --workspace --open 309 - ``` 310 - 311 - ## License 312 - 313 - This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 314 - 315 - ## Architecture 316 - 317 - These components are designed to work together as building blocks for AT Protocol applications: 318 - 319 - - **Data Foundation Layer**: `atproto-dasl` provides CID computation, deterministic DAG-CBOR encoding, CAR v1 archives, and pluggable block storage 320 - - **Identity Layer**: `atproto-identity` provides the foundation for DID resolution and cryptographic operations 321 - - **Repository Layer**: `atproto-repo` provides Merkle Search Tree operations, commit structures, and repository handling 322 - - **Data Layer**: `atproto-record` and `atproto-attestation` handle record operations, CID generation, and cryptographic attestations 323 - - **Schema Layer**: `atproto-lexicon` provides lexicon resolution and validation for AT Protocol schemas 324 - - **Authentication Layer**: `atproto-oauth*` crates handle complete OAuth 2.0 flows with AT Protocol security extensions 325 - - **Application Layer**: `atproto-client` and `atproto-xrpcs*` enable client applications and service development 326 - - **Event Layer**: `atproto-jetstream` and `atproto-tap` provide real-time event processing capabilities 327 - - **Utilities Layer**: `atproto-extras` provides rich text facet parsing for AT Protocol applications 328 - 329 - ## Use Cases 330 - 331 - This workspace enables development of: 332 - 333 - - **AT Protocol Identity Providers (AIPs)** - Complete OAuth servers with DID-based authentication 334 - - **Personal Data Servers (PDS)** - XRPC services with JWT authorization and repository management 335 - - **AT Protocol Clients** - Applications that authenticate and interact with AT Protocol services 336 - - **Event Processing Systems** - Real-time processors for AT Protocol repository events via Jetstream or TAP 337 - - **Repository Tools** - CAR file inspection, MST analysis, and repository verification utilities 338 - - **Development Tools** - CLI utilities for testing, debugging, and managing AT Protocol identities 339 - 340 - ## Contributing 341 - 342 - Contributions are welcome! This project follows standard Rust development practices: 1 + # atproto-crates 343 2 344 - 1. Fork this repository 345 - 2. Create a feature branch 346 - 3. Run tests: `cargo test` 347 - 4. Run linting: `cargo fmt && cargo clippy` 348 - 5. Submit a pull request 3 + This project has a new home at: https://tangled.org/ngerakines.me/atproto-crates 349 4 350 - ## Acknowledgments 351 - 352 - Parts of this project were extracted from the [smokesignal.events](https://tangled.sh/@smokesignal.events/smokesignal) project, an open-source AT Protocol event and RSVP management application. This extraction enables broader community use and contribution to AT Protocol tooling in Rust.