Module workflow

Source
Expand description

OAuth workflow implementation for AT Protocol authorization flows. OAuth workflow implementation for AT Protocol authorization flows.

This module provides a complete OAuth 2.0 authorization code flow implementation specifically designed for AT Protocol, including Pushed Authorization Requests (PAR), DPoP security, PKCE protection, and client assertion handling.

§OAuth Flow Components

  • oauth_init(): Initiates OAuth flow with PAR request to authorization server
  • oauth_complete(): Completes OAuth flow by exchanging authorization code for tokens
  • OAuthClient: Client configuration with credentials and signing keys
  • OAuthRequest: Tracking structure for ongoing authorization requests
  • OAuthRequestState: Security parameters including state, nonce, and PKCE challenge

§Security Features

  • PKCE: Proof Key for Code Exchange protection against authorization code interception
  • DPoP: Demonstration of Proof-of-Possession for token binding
  • Client Assertions: JWT-based client authentication using private key signatures
  • State Parameters: CSRF protection using random state values
  • Nonce Values: Additional replay protection

§Example Usage

use atproto_oauth::workflow::{oauth_init, oauth_complete, OAuthClient, OAuthRequestState};
use atproto_oauth::pkce::generate;
use atproto_identity::key::generate_key;

// Generate security parameters
let signing_key = generate_key(KeyType::P256Private)?;
let dpop_key = generate_key(KeyType::P256Private)?;
let (pkce_verifier, code_challenge) = generate();

// Configure OAuth client
let oauth_client = OAuthClient {
    redirect_uri: "https://app.example.com/callback".to_string(),
    client_id: "https://app.example.com/client-metadata.json".to_string(),
    private_signing_key_data: signing_key,
};

// Create request state
let oauth_state = OAuthRequestState {
    state: "random-state-value".to_string(),
    nonce: "random-nonce-value".to_string(),
    code_challenge,
    scope: "atproto transition:generic".to_string(),
};

// Initiate OAuth flow
let par_response = oauth_init(
    &http_client,
    &oauth_client,
    &dpop_key,
    "user.bsky.social",
    &authorization_server,
    &oauth_state,
).await?;

// Build authorization URL
let auth_url = format!(
    "{}?client_id={}&request_uri={}",
    authorization_server.authorization_endpoint,
    oauth_client.client_id,
    par_response.request_uri
);

// After user authorization and callback...
let token_response = oauth_complete(
    &http_client,
    &oauth_client,
    &dpop_key,
    "authorization_code_from_callback",
    &oauth_request,
    &did_document,
).await?;

Structs§

OAuthClient
OAuth client configuration containing essential client credentials.
OAuthRequest
OAuth request tracking information for ongoing authorization flows.
OAuthRequestState
OAuth request state containing security parameters for the authorization flow.
ParResponse
Response from a Pushed Authorization Request (PAR) endpoint.
TokenResponse
Response from the OAuth token endpoint containing access credentials.

Functions§

oauth_complete
Completes the OAuth authorization flow by exchanging the authorization code for tokens.
oauth_init
Initiates the OAuth authorization flow by making a Pushed Authorization Request (PAR).
oauth_refresh
Refreshes OAuth access tokens using a refresh token.