Package-level declarations

AtOAuth flow orchestrator, DpopAuthProvider, OAuthSession(Store), DpopSigner, and the exceptions thrown when a session expires or a step in the OAuth flow fails.

Types

Link copied to clipboard
class AtOAuth(clientMetadataUrl: String, redirectUri: String, sessionStore: OAuthSessionStore, httpClient: HttpClient, json: Json = Json { ignoreUnknownKeys = true }, scope: String = "atproto transition:generic", onSessionPersistFailure: (Throwable) -> Unit = {}, pendingStore: PendingAuthStore = InMemoryPendingAuthStore(), nowMillis: () -> Long = { System.currentTimeMillis() })

AT Protocol OAuth 2.0 flow orchestrator for public clients.

Link copied to clipboard
data class AuthServerMetadata(val issuer: String, val authorizationEndpoint: String, val tokenEndpoint: String, val parEndpoint: String, val revocationEndpoint: String?, val pdsUrl: String?, val did: String?, val handle: String?, val promptValuesSupported: List<String> = emptyList())

Resolved authorization server metadata — everything the OAuth flow needs to construct PAR requests, authorization URLs, and token exchange calls.

Link copied to clipboard
class DiscoveryChain(httpClient: HttpClient, json: Json = Json { ignoreUnknownKeys = true })

Implements the AT Protocol discovery chain:

Link copied to clipboard
class DpopAuthProvider(session: OAuthSession, signer: DpopSigner, sessionStore: OAuthSessionStore, refreshClient: HttpClient, json: Json = Json { ignoreUnknownKeys = true }, onPersistFailure: (Throwable) -> Unit = {}) : AuthProvider

AuthProvider implementation that attaches DPoP proof-of-possession headers on every XRPC request and handles token refresh transparently.

Link copied to clipboard

Signs DPoP proof JWTs using EC P-256 (ES256) per RFC 9449.

Link copied to clipboard

Default PendingAuthStore: keeps the pending login in memory only.

Link copied to clipboard
class OAuthDiscoveryException(message: String, cause: Throwable? = null) : RuntimeException
Link copied to clipboard
class OAuthException(message: String, cause: Throwable? = null) : RuntimeException
Link copied to clipboard

Thrown when a token refresh could not be completed for a reason that does NOT prove the refresh token is dead — a network failure, a 5xx/429/408, an unparseable (e.g. captive-portal) body, or any non-invalid_grant error response — as opposed to a genuinely revoked/expired refresh token (error=invalid_grant, which is OAuthSessionExpiredException).

Link copied to clipboard
@Serializable
data class OAuthSession(val accessToken: String, val refreshToken: String, val did: String?, val handle: String?, val pdsUrl: String?, val tokenEndpoint: String, val revocationEndpoint: String? = null, val clientId: String? = null, val dpopPrivateKey: ByteArray, val dpopPublicKey: ByteArray, val authServerNonce: String? = null, val clockOffsetSeconds: Long = 0, val pdsNonce: String? = null)

Persisted OAuth session state. Contains everything needed to make authenticated XRPC requests and refresh the session when the access token expires.

Link copied to clipboard
Link copied to clipboard

Platform-agnostic session persistence interface. Consumers provide the storage backend — the module handles serialization.

Link copied to clipboard
class OAuthSignupNotSupportedException(val authServerUrl: String, val advertisedPromptValues: List<String>) : RuntimeException

Thrown by AtOAuth.beginSignup when the configured authorization server's /.well-known/oauth-authorization-server metadata does not advertise "create" in prompt_values_supported. Per OIDC Prompt Create 1.0 the prompt=create value tells the server "render the signup UI"; servers that don't advertise the value may silently ignore it or reject the PAR.

Link copied to clipboard
@Serializable
data class PendingAuth(val state: String, val codeVerifier: String, val redirectUri: String, val flowOrigin: String, val authServerNonce: String?, val dpopPrivateKey: ByteArray, val dpopPublicKey: ByteArray, val issuer: String, val authorizationEndpoint: String, val tokenEndpoint: String, val parEndpoint: String, val revocationEndpoint: String? = null, val pdsUrl: String? = null, val did: String? = null, val handle: String? = null, val promptValuesSupported: List<String> = emptyList(), val createdAtEpochMillis: Long = 0)

The in-flight half of an OAuth login, captured between beginLogin / beginSignup and AtOAuth.completeLogin.

Link copied to clipboard

Platform-agnostic persistence for the in-flight login (PendingAuth). Consumers provide the storage backend — the module handles serialization.