#oauth #oauth2 #flows #secure #validation #atprotocol #jwk #protocols #d-po-p

atproto-oauth

OAuth workflow implementation for AT Protocol - PKCE, DPoP, and secure authentication flows

14 releases (5 breaking)

Uses new Rust 2024

new 0.9.7 Jul 13, 2025
0.9.6 Jul 11, 2025
0.9.2 Jun 30, 2025
0.8.1 Jun 21, 2025
0.4.1 Jun 3, 2025

#288 in Authentication

Download history 353/week @ 2025-06-03 46/week @ 2025-06-10 453/week @ 2025-06-17 369/week @ 2025-06-24 314/week @ 2025-07-01 603/week @ 2025-07-08

1,752 downloads per month
Used in 5 crates

MIT license

450KB
6.5K SLoC

atproto-oauth

OAuth 2.0 implementation for AT Protocol with DPoP support, PKCE, and JWT operations.

Overview

atproto-oauth provides comprehensive OAuth 2.0 functionality specifically designed for the AT Protocol ecosystem. This library implements DPoP (Demonstration of Proof-of-Possession), PKCE (Proof Key for Code Exchange), JWT operations, JWK management, and AT Protocol-specific OAuth validation.

Features

  • JWT operations: Minting, verification, and validation with ES256/ES256K/ES384 support
  • JWK management: Generation and conversion for P-256, P-384, and K-256 curves
  • PKCE implementation: Secure OAuth flows with Proof Key for Code Exchange
  • DPoP support: Demonstration of Proof-of-Possession with automatic retry middleware
  • OAuth discovery: Resource discovery and AT Protocol validation
  • Request storage: LRU cache-based OAuth request storage
  • Structured errors: Comprehensive error handling with detailed error codes

Usage

JWT Operations

use atproto_oauth::jwt::{mint, verify, Header, Claims, JoseClaims};
use atproto_identity::key::identify_key;

let key_data = identify_key("did:key:zQ3sh...")?;

let header = Header {
    algorithm: Some("ES256".to_string()),
    type_: Some("JWT".to_string()),
    ..Default::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()),
    expiration: Some(chrono::Utc::now().timestamp() as u64 + 3600),
    ..Default::default()
});

let token = mint(&key_data, &header, &claims)?;
verify(&key_data, &token).await?;

PKCE Flow

use atproto_oauth::pkce;

let (code_verifier, code_challenge) = pkce::generate();
// Use code_challenge in authorization URL
// Later use code_verifier for token exchange

DPoP Proofs

use atproto_oauth::dpop::{auth_dpop, request_dpop};

let (dpop_token, header, claims) = auth_dpop(
    &key_data,
    "POST",
    "https://auth.example.com/oauth/token"
)?;

OAuth Discovery

use atproto_oauth::resources::{discover_protected_resource, discover_authorization_server};

let protected_resource = discover_protected_resource(&client, pds_url).await?;
let auth_server = discover_authorization_server(&client, auth_server_url).await?;

License

MIT License

Dependencies

~28–60MB
~1M SLoC