# AT Protocol Identity Rust Components A comprehensive collection of Rust components for creating AT Protocol applications. This workspace provides essential building blocks for identity management, record operations, OAuth 2.0 authentication flows, HTTP client operations, XRPC services, and real-time event streaming. **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. ## Components This workspace contains 10 specialized crates that work together to provide complete AT Protocol application development capabilities: ### Identity & Cryptography - **[`atproto-identity`](crates/atproto-identity/)** - Core identity management with multi-method DID resolution (plc, web, key), DNS/HTTP handle resolution, and P-256/P-384/K-256 cryptographic operations. *Includes 4 CLI tools.* - **[`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.* - **[`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.* - **[`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.* ### Authentication & Authorization - **[`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.* - **[`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. - **[`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.* ### Client & Service Development - **[`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 3 CLI tools.* - **[`atproto-xrpcs`](crates/atproto-xrpcs/)** - XRPC service framework providing JWT authorization extractors, DID resolution integration, and Axum middleware for building AT Protocol services. - **[`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.* ### Real-time Event Processing - **[`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.* ## Quick Start Add the crates to your `Cargo.toml`: ```toml [dependencies] atproto-identity = "0.13.0" atproto-attestation = "0.13.0" atproto-record = "0.13.0" atproto-lexicon = "0.13.0" atproto-oauth = "0.13.0" atproto-oauth-aip = "0.13.0" atproto-client = "0.13.0" # Add others as needed ``` ### Basic Identity Resolution ```rust use atproto_identity::resolve::{resolve_subject, create_resolver}; #[tokio::main] async fn main() -> anyhow::Result<()> { let http_client = reqwest::Client::new(); let dns_resolver = create_resolver(&[]); let did = resolve_subject(&http_client, &dns_resolver, "alice.bsky.social").await?; println!("Resolved DID: {}", did); Ok(()) } ``` ### Lexicon Resolution ```rust use atproto_lexicon::resolve::{DefaultLexiconResolver, LexiconResolver}; use atproto_identity::resolve::HickoryDnsResolver; #[tokio::main] async fn main() -> anyhow::Result<()> { let http_client = reqwest::Client::new(); let dns_resolver = HickoryDnsResolver::create_resolver(&[]); let resolver = DefaultLexiconResolver::new(http_client, dns_resolver); // Resolve a lexicon schema let lexicon = resolver.resolve("app.bsky.feed.post").await?; println!("Lexicon schema: {}", serde_json::to_string_pretty(&lexicon)?); Ok(()) } ``` ### Record Signing ```rust use atproto_identity::key::{identify_key, to_public}; use atproto_attestation::{ create_inline_attestation, verify_all_signatures, VerificationStatus, input::{AnyInput, PhantomSignature} }; use serde_json::json; #[tokio::main] async fn main() -> anyhow::Result<()> { let private_key = identify_key("did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA")?; let public_key = to_public(&private_key)?; let key_reference = format!("{}", &public_key); let repository_did = "did:plc:repo123"; let record = json!({ "$type": "app.bsky.feed.post", "text": "Hello AT Protocol!", "createdAt": "2024-01-01T00:00:00.000Z" }); let sig_metadata = json!({ "$type": "com.example.inlineSignature", "key": &key_reference, "issuer": "did:plc:issuer123", "issuedAt": "2024-01-01T00:00:00.000Z" }); let signed_record = create_inline_attestation::( AnyInput::Json(record), AnyInput::Json(sig_metadata), repository_did, &private_key )?; let reports = verify_all_signatures(&signed_record, repository_did, None).await?; assert!(reports.iter().all(|report| matches!(report.status, VerificationStatus::Valid { .. }))); Ok(()) } ``` ### XRPC Service ```rust use atproto_xrpcs::authorization::Authorization; use axum::{Json, Router, extract::Query, routing::get}; use serde::Deserialize; use serde_json::json; #[derive(Deserialize)] struct HelloParams { subject: Option, } async fn handle_hello( params: Query, authorization: Option, ) -> Json { let subject = params.subject.as_deref().unwrap_or("World"); let message = if let Some(auth) = authorization { format!("Hello, authenticated {}! (caller: {})", subject, auth.subject()) } else { format!("Hello, {}!", subject) }; Json(json!({ "message": message })) } #[tokio::main] async fn main() -> anyhow::Result<()> { let app = Router::new() .route("/xrpc/com.example.hello", get(handle_hello)) .with_state(your_web_context); let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?; axum::serve(listener, app).await?; Ok(()) } ``` ### OAuth Client Flow ```rust use atproto_oauth_aip::{OAuthClient, oauth_init, oauth_complete, session_exchange}; use atproto_oauth::storage::MemoryStorage; #[tokio::main] async fn main() -> anyhow::Result<()> { let client = OAuthClient::new( "https://your-app.com/client-id".to_string(), Some("your-client-secret".to_string()), "https://your-app.com/callback".to_string(), ); let storage = MemoryStorage::new(); // Start OAuth flow let (authorization_url, state) = oauth_init( &client, "alice.bsky.social", &storage, ).await?; println!("Visit: {}", authorization_url); // After callback with code... let access_token = oauth_complete( &client, "auth-code", "state", &storage, ).await?; // Get AT Protocol session let session = session_exchange(&client, &access_token, &storage).await?; println!("Authenticated as: {} ({})", session.handle, session.did); Ok(()) } ``` ## Command Line Tools The workspace includes 13 command-line tools across multiple crates, providing ready-to-use utilities for AT Protocol development and testing. All CLI tools require the `clap` feature: ```bash # Build with CLI support cargo build --features clap --bins # Identity operations (atproto-identity crate) cargo run --features clap --bin atproto-identity-resolve -- alice.bsky.social cargo run --features clap --bin atproto-identity-key -- generate p256 cargo run --features clap --bin atproto-identity-sign -- did:key:... data.json cargo run --features clap --bin atproto-identity-validate -- did:key:... data.json signature # Attestation operations (atproto-attestation crate) cargo run --package atproto-attestation --features clap,tokio --bin atproto-attestation-sign -- inline record.json did:key:... metadata.json cargo run --package atproto-attestation --features clap,tokio --bin atproto-attestation-verify -- signed_record.json # Record operations (atproto-record crate) cat record.json | cargo run --features clap --bin atproto-record-cid # Lexicon operations (atproto-lexicon crate) cargo run --features clap,hickory-dns --bin atproto-lexicon-resolve -- app.bsky.feed.post # Client operations (atproto-client crate) cargo run --features clap --bin atproto-client-auth -- login alice.bsky.social password123 cargo run --features clap --bin atproto-client-app-password -- alice.bsky.social access_token /xrpc/com.atproto.repo.listRecords cargo run --features clap --bin atproto-client-dpop -- alice.bsky.social did:key:... access_token /xrpc/com.atproto.repo.listRecords # OAuth operations (atproto-oauth crate) cargo run --features clap --bin atproto-oauth-service-token -- [service-token-args] # OAuth operations (atproto-oauth-axum crate) cargo run --features clap --bin atproto-oauth-tool -- login did:key:... alice.bsky.social # XRPC service (atproto-xrpcs-helloworld crate) cargo run --bin atproto-xrpcs-helloworld # Event streaming (atproto-jetstream crate) cargo run --features clap --bin atproto-jetstream-consumer -- jetstream1.us-east.bsky.network dictionary.zstd ``` ## Development ```bash # Build all crates cargo build # Run all tests cargo test # Format and lint cargo fmt && cargo clippy # Generate documentation cargo doc --workspace --open ``` ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Architecture These components are designed to work together as building blocks for AT Protocol applications: - **Identity Layer**: `atproto-identity` provides the foundation for DID resolution and cryptographic operations - **Authentication Layer**: `atproto-oauth*` crates handle complete OAuth 2.0 flows with AT Protocol security extensions - **Application Layer**: `atproto-client` and `atproto-xrpcs*` enable client applications and service development - **Data Layer**: `atproto-record` handles record signing and verification with proper IPLD serialization - **Event Layer**: `atproto-jetstream` provides real-time event processing capabilities ## Use Cases This workspace enables development of: - **AT Protocol Identity Providers (AIPs)** - Complete OAuth servers with DID-based authentication - **Personal Data Servers (PDS)** - XRPC services with JWT authorization and repository management - **AT Protocol Clients** - Applications that authenticate and interact with AT Protocol services - **Event Processing Systems** - Real-time processors for AT Protocol repository events - **Development Tools** - CLI utilities for testing, debugging, and managing AT Protocol identities ## Contributing Contributions are welcome! This project follows standard Rust development practices: 1. Fork this repository 2. Create a feature branch 3. Run tests: `cargo test` 4. Run linting: `cargo fmt && cargo clippy` 5. Submit a pull request ## Acknowledgments 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.