oauth
AT Protocol OAuth 2.0 module for public clients (Android and JVM desktop apps). JVM-only — java.security is used for EC P-256 key generation and signing so no external JWT library is pulled in.
What's in here
AtOAuth— flow orchestrator.beginLogin(handle)resolves the handle to DID → PDS → authorization server, runs Pushed Authorization Request (PAR) with PKCE + DPoP, and returns an authorization URL to open in a browser.completeLogin(redirectUri)exchanges the code for DPoP-bound tokens and persists the session.createClient()returns anXrpcClientwith aDpopAuthProviderthat handles token refresh and DPoP nonce rotation transparently.DpopAuthProvider—AuthProviderimplementation that attachesAuthorization: DPoP <token>+DPoP: <proof>headers on every request, rotates nonces on 401, and refreshes access tokens.OAuthSession/OAuthSessionStore— serializable session carrying the DPoP private key + tokens, plus aSessionStoreinterface for persistence. Consumer apps implementSessionStore(typically backed byEncryptedSharedPreferenceson Android).DpopSigner— EC P-256 DPoP JWT signer built onjava.security. Calibrates its clock against the server'sDateheader to preventiatrejection on devices with clock drift.Discovery — handle → DID (DNS-over-HTTPS + HTTP fallback) → PDS → authorization server metadata resolution.
PKCE — S256 challenge + verifier generation.
Security properties
DPoP (RFC 9449) proof-of-possession binds access tokens to a per-client EC P-256 keypair. Stolen tokens cannot be replayed without the private key.
PKCE S256 (RFC 7636) prevents authorization-code interception.
State +
iss+subvalidation on the redirect guards against CSRF, mix-up attacks, and account mismatches.Independent nonce tracking for PDS and authorization server ensures nonce rotation is handled correctly per endpoint.
Use with Android
See the atproto-oauth skill for a complete Android walkthrough: hosting the client-metadata JSON, configuring the AndroidManifest intent filter, implementing an encrypted OAuthSessionStore, driving the flow from a ViewModel, and capturing the Custom Tabs redirect. A working reference app lives at samples/android.