AtOAuth
AT Protocol OAuth 2.0 flow orchestrator for public clients.
Implements the full authorization flow: handle → DID → PDS → authorization server discovery, PAR with PKCE + DPoP, browser-based authorization, token exchange, and session management with transparent refresh.
Supports two entry points:
beginLogin — keyed on a user's handle/DID; full discovery chain.
beginSignup — keyed on a known auth server (default
bsky.social); short-circuits discovery and sends OIDCprompt=createso the auth server renders its signup UI. Identity is hydrated post-token-exchange.
Both flows complete via completeLogin — the redirect handling is shared.
Consumer usage
val oauth = AtOAuth(
clientMetadataUrl = "https://example.app/oauth/client-metadata.json",
redirectUri = "app.example:/oauth-redirect",
sessionStore = mySessionStore,
httpClient = myKtorClient,
)
// Login path:
val authUrl = oauth.beginLogin("alice.bsky.social")
// Signup path:
val signupUrl = oauth.beginSignup() // defaults to bsky.social
// Both paths: open the URL in a browser, then call:
oauth.completeLogin(redirectUri)
val client = oauth.createClient()Requesting additional scopes
To request umbrella scopes beyond the default atproto transition:generic (e.g. transition:chat.bsky for Bluesky chat, transition:email for email), pass them via scope. The value must be a subset of the scope field declared in the hosted client-metadata.json document.
val oauth = AtOAuth(
clientMetadataUrl = "...",
redirectUri = "app.example:/oauth-redirect",
sessionStore = ...,
httpClient = ...,
scope = "atproto transition:generic transition:chat.bsky",
)The value must be a subset of the scope field declared in the hosted client metadata document.
Constructors
Functions
Starts the OAuth login flow.
Starts the OAuth signup flow against a known authorization server.
Completes the OAuth login flow after the browser redirects back.
Creates an authenticated XrpcClient from the persisted session. The client uses DpopAuthProvider for DPoP proof-of-possession on every request.