AT Protocol Identity & Record Library#
A comprehensive Rust library for AT Protocol identity management, record signing, verification, and OAuth operations. This library provides full functionality for DID resolution, handle resolution, identity document management, cryptographic record operations, and OAuth 2.0 flows across multiple DID methods.
This project was extracted from the open-sourced Smokesignal project and is released under the MIT license.
Project Overview#
This workspace provides a complete toolkit for AT Protocol operations including identity resolution, record signing/verification, OAuth 2.0 flows, HTTP client operations, and web server integration. The library is designed to be modular, secure, and fully compliant with AT Protocol specifications.
Crates#
This workspace contains five specialized crates:
atproto-identity#
Core identity management and cryptographic operations
- DID Resolution: Support for
did:plc,did:web, anddid:keymethods - Handle Resolution: DNS and HTTP-based handle resolution with validation
- Identity Documents: Complete DID document parsing and management
- Cryptographic Operations: P-256 and K-256 elliptic curve support with signing/verification
- Key Management: DID key identification, conversion, and JWK generation
- Validation: Input validation for handles and DIDs
- Configuration: Environment-based configuration with DNS and certificate customization
atproto-record#
AT Protocol record signature operations
- Record Signing: Create cryptographic signatures for AT Protocol records with proper
$sigobject handling - Signature Verification: Verify existing signatures against records and public keys
- IPLD Integration: Proper IPLD DAG-CBOR serialization for consistent signature generation
- Multi-curve Support: Support for P-256 and K-256 elliptic curves via
atproto-identity - Repository Context: Include repository and collection context in signatures
atproto-oauth#
Complete OAuth 2.0 operations with AT Protocol extensions
- JWT Operations: Complete JSON Web Token minting, verification, and validation with ES256/ES256K support
- JWK Management: JSON Web Key generation and management for P-256 and K-256 curves
- PKCE Implementation: RFC 7636 Proof Key for Code Exchange for secure OAuth flows
- DPoP Support: RFC 9449 Demonstration of Proof-of-Possession with automatic retry middleware
- OAuth Resource Discovery: RFC 8414 OAuth 2.0 authorization server and protected resource metadata discovery
- AT Protocol Validation: Comprehensive validation of OAuth servers against AT Protocol requirements
atproto-client#
HTTP client library for AT Protocol services
- HTTP Client Operations: Authenticated and unauthenticated HTTP GET/POST requests with JSON support
- DPoP Authentication: RFC 9449 Demonstration of Proof-of-Possession with automatic retry middleware
- Repository Operations: Complete CRUD operations for AT Protocol repository records
- URL Building: Flexible URL construction with parameter encoding and query string generation
- OAuth Integration: Seamless integration with
atproto-oauthfor DPoP authentication
atproto-oauth-axum#
Axum web handlers for OAuth 2.0 authorization server endpoints
- Complete OAuth Server Handlers: Ready-to-use Axum handlers for all required OAuth 2.0 endpoints
- Client Metadata Endpoint: RFC 7591 compliant client metadata for dynamic client registration
- JWKS Endpoint: JSON Web Key Set serving for JWT signature verification
- Authorization Callback Handler: Complete OAuth callback processing with token exchange
- OAuth Login CLI Tool: Full-featured command-line tool for testing and development OAuth flows
Command Line Tools#
The library includes 7 command-line utilities across the crates:
Identity Operations (atproto-identity)#
atproto-identity-resolve- Resolve AT Protocol handles and DIDs to identity documentsatproto-identity-sign- Sign JSON data with DID keys using IPLD DAG-CBOR serializationatproto-identity-validate- Verify cryptographic signatures of JSON dataatproto-identity-key- Generate and manage cryptographic keys (P-256/K-256)
Record Operations (atproto-record)#
atproto-record-sign- Sign AT Protocol records with embedded signature metadataatproto-record-verify- Verify AT Protocol record signatures with issuer authentication
OAuth Operations (atproto-oauth-axum)#
atproto-oauth-tool- Complete OAuth client flow with local server and token acquisition
Quick Start#
Add the crates to your Cargo.toml:
[dependencies]
atproto-identity = "0.4.1"
atproto-record = "0.4.1"
atproto-oauth = "0.4.1"
atproto-client = "0.4.1"
atproto-oauth-axum = "0.4.1"
Basic Identity Resolution#
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(&[]);
// Resolve a handle to a DID
let did = resolve_subject(&http_client, &dns_resolver, "alice.bsky.social").await?;
println!("Resolved DID: {}", did);
Ok(())
}
Record Signing and Verification#
use atproto_identity::key::identify_key;
use atproto_record::signature;
use serde_json::json;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Parse DID key for signing operations
let signing_key = identify_key("did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA")?;
// Create a record to sign
let record = json!({
"$type": "app.bsky.feed.post",
"text": "Hello AT Protocol!",
"createdAt": "2024-01-01T00:00:00.000Z"
});
// Create signature object with issuer and timestamp
let signature_object = json!({
"issuer": "did:plc:issuer123",
"issuedAt": "2024-01-01T00:00:00.000Z"
});
// Sign the record
let signed_record = signature::create(
&signing_key,
&record,
"did:plc:user123", // repository
"app.bsky.feed.post", // collection
signature_object,
).await?;
// Verify the signature
signature::verify(
"did:plc:issuer123", // issuer
&signing_key, // verification key
signed_record, // signed record
"did:plc:user123", // repository
"app.bsky.feed.post", // collection
).await?;
println!("Signature verification successful");
Ok(())
}
OAuth Operations#
use atproto_oauth::jwt::{mint, Header, Claims, JoseClaims};
use atproto_oauth::pkce;
use atproto_identity::key::identify_key;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let key_data = identify_key("did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA")?;
// Generate PKCE parameters
let (code_verifier, code_challenge) = pkce::generate();
println!("PKCE Challenge: {}", code_challenge);
// Create and sign JWT
let header = Header::default();
let claims = Claims::new(JoseClaims {
issuer: Some("did:plc:issuer123".to_string()),
subject: Some("did:plc:subject456".to_string()),
audience: Some("https://pds.example.com".to_string()),
..Default::default()
});
let token = mint(&key_data, &header, &claims)?;
println!("JWT: {}", token);
Ok(())
}
CLI Usage Examples#
# Resolve a handle or DID to identity document
cargo run --bin atproto-identity-resolve alice.bsky.social
# Get full DID document with verification methods
cargo run --bin atproto-identity-resolve --did-document did:plc:user123
# Generate a new P-256 private key
cargo run --bin atproto-identity-key generate p256
# Sign a record from file with all required context
cargo run --bin atproto-record-sign \
did:key:zQ3shNzMp4oaaQ1... \
did:plc:issuer123 \
record.json \
repository=did:plc:user123 \
collection=app.bsky.feed.post
# Verify a signed record
cargo run --bin atproto-record-verify \
did:plc:issuer123 \
did:key:zQ3shNzMp4oaaQ1... \
signed_record.json \
repository=did:plc:user123 \
collection=app.bsky.feed.post
# Start OAuth login flow (requires EXTERNAL_BASE environment variable)
EXTERNAL_BASE=localhost:8080 cargo run --bin atproto-oauth-tool login \
did:key:zQ3shNzMp4oaaQ1... \
alice.bsky.social
Features#
- Async/Await: Built with modern Rust async patterns using Tokio
- Error Handling: Comprehensive structured error types using
thiserrorwith standardized error codes - Security: Forbids unsafe code, follows security best practices, and implements all required OAuth security extensions
- Standards Compliance: Full AT Protocol, RFC 7636 (PKCE), RFC 9449 (DPoP), and RFC 8414 (OAuth Discovery) compliance
- Logging: Structured logging with
tracingfor debugging and monitoring - Multi-platform: Works on all major platforms with configurable DNS and HTTP settings
- Modular Design: Clean separation of concerns allowing selective usage of components
Architecture#
The library follows a layered architecture with clear separation of concerns:
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
│ (CLI Tools & Web Handlers) │
├─────────────────────────────────────────────────────────────┤
│ Protocol Layer │
│ (atproto-client, atproto-record) │
├─────────────────────────────────────────────────────────────┤
│ OAuth Layer │
│ (atproto-oauth, atproto-oauth-axum) │
├─────────────────────────────────────────────────────────────┤
│ Foundation Layer │
│ (atproto-identity - Core Services) │
└─────────────────────────────────────────────────────────────┘
- Foundation Layer: Core identity, cryptographic, and DID operations
- OAuth Layer: Complete OAuth 2.0 flows with AT Protocol extensions
- Protocol Layer: Higher-level AT Protocol operations (records, client)
- Application Layer: Ready-to-use tools and web framework integration
Development#
Building the Project#
# Build all crates
cargo build
# Build specific crate
cargo build -p atproto-identity
# Build with all features
cargo build --all-features
Running Tests#
# Run all tests
cargo test
# Run tests for specific crate
cargo test -p atproto-oauth
# Run with output
cargo test -- --nocapture
Code Quality#
# Format code
cargo fmt
# Lint code
cargo clippy
# Check without building
cargo check
# Run all quality checks
cargo fmt && cargo clippy && cargo test
Documentation#
# Generate documentation
cargo doc --open
# Generate documentation for all crates
cargo doc --workspace --open
License#
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing#
Contributions are welcome! Please ensure that:
- All tests pass:
cargo test - Code is properly formatted:
cargo fmt - No linting issues:
cargo clippy - New functionality includes appropriate tests and documentation
- Error handling follows the project's structured error format
Acknowledgments#
This library was extracted from the Smokesignal project, an open-source event and RSVP management and discovery application. We thank the Smokesignal contributors for their foundational work on AT Protocol identity management and record operations.