atproto-oauth-aip#
AT Protocol OAuth implementation for AT Protocol Identity Provider (AIP) integration. This crate provides high-level OAuth workflow functions for client applications that need to authenticate with AT Protocol services.
Overview#
atproto-oauth-aip builds on top of the foundational atproto-oauth crate to provide a complete OAuth authentication workflow specifically tailored for AT Protocol. It handles the full OAuth flow including:
- OAuth metadata discovery
- Pushed Authorization Request (PAR) initiation
- Authorization code exchange
- AT Protocol session establishment
Features#
- PAR Support: Enhanced security through Pushed Authorization Requests
- AT Protocol Session Exchange: Convert OAuth tokens to rich AT Protocol sessions
- DPoP Integration: Support for Demonstration of Proof-of-Possession tokens
- Comprehensive Error Handling: Typed errors for each OAuth operation
- Async/Await: Fully asynchronous implementation using Tokio
Installation#
Add this to your Cargo.toml:
[dependencies]
atproto-oauth-aip = "0.9.7"
Usage#
Basic OAuth Flow#
use atproto_oauth_aip::{OAuthClient, oauth_init, oauth_complete, session_exchange};
use atproto_oauth::storage::MemoryStorage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize OAuth client
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(),
);
// Initialize storage (use persistent storage in production)
let storage = MemoryStorage::new();
// Start OAuth flow
let (authorization_url, state) = oauth_init(
&client,
"user@example.com", // User identifier
&storage,
).await?;
// Redirect user to authorization_url
println!("Please visit: {}", authorization_url);
// After user authorizes and is redirected back with code and state...
let authorization_code = "received-auth-code";
let returned_state = "returned-state";
// Complete OAuth flow
let access_token = oauth_complete(
&client,
authorization_code,
returned_state,
&storage,
).await?;
// Exchange for AT Protocol session
let session = session_exchange(
&client,
&access_token,
&storage,
).await?;
println!("Authenticated as: {} ({})", session.handle, session.did);
println!("PDS Endpoint: {}", session.pds_endpoint);
Ok(())
}
Fetching OAuth Metadata#
use atproto_oauth_aip::resources::{oauth_protected_resource, oauth_authorization_server};
// Get OAuth protected resource configuration
let protected_resource = oauth_protected_resource("https://bsky.social").await?;
// Get OAuth authorization server metadata
let auth_server = oauth_authorization_server(&protected_resource).await?;
API Documentation#
Core Types#
OAuthClient: OAuth client credentials and configurationATProtocolSession: Authenticated session containing DID, handle, and PDS endpoint
Main Functions#
oauth_init(): Initiates OAuth flow using PARoauth_complete(): Exchanges authorization code for access tokensession_exchange(): Converts OAuth access token to AT Protocol session
Resource Functions#
oauth_protected_resource(): Fetch OAuth protected resource metadataoauth_authorization_server(): Fetch OAuth authorization server metadata
Error Handling#
The crate uses typed errors following the AT Protocol error format:
use atproto_oauth_aip::OAuthWorkflowError;
match result {
Err(OAuthWorkflowError::InvalidAuthorizationRequest(e)) => {
// Handle PAR errors
}
Err(OAuthWorkflowError::TokenExchangeFailed(e)) => {
// Handle token exchange errors
}
// ... other error types
}
Storage Requirements#
This crate requires an implementation of the OAuthStorage trait from atproto-oauth. For production use, implement persistent storage rather than using MemoryStorage.
Security Considerations#
- Always use HTTPS URLs for OAuth endpoints
- Implement proper state validation to prevent CSRF attacks
- Store client secrets securely
- Use persistent storage with appropriate security measures
- Validate DPoP keys when required by the authorization server
Dependencies#
This crate depends on:
atproto-oauth: Core OAuth implementationatproto-identity: AT Protocol identity resolutionatproto-record: Record handlingreqwest: HTTP clientserde: Serializationtokio: Async runtime
License#
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.
Contributing#
Contributions are welcome! Please feel free to submit a Pull Request.