AT Protocol OAuth
OAuth is the account authorization system for AT Protocol clients. It lets an app obtain permission to call a user’s Personal Data Server (PDS) without asking for the user’s password.
The unusual part is not OAuth itself. The unusual part is where OAuth runs. AT Protocol has many PDS hosts and can use separate authorization servers, sometimes called entryways. A client therefore begins by discovering authority. It cannot hard-code one login domain and call the result authentication.
Why OAuth Is Part of the Protocol
Section titled “Why OAuth Is Part of the Protocol”A client needs three facts before it can make authorized XRPC calls:
- which account it is acting for;
- which PDS currently hosts that account;
- which permissions the user granted.
In AT Protocol, the stable account identifier is the DID. Handles help humans find accounts, but handles can change. PDS hosts can also change. OAuth has to respect that portability rather than smuggle in a central account database.
The result is a profile of OAuth that does two jobs:
- it authorizes access to PDS resources;
- it authenticates the AT Protocol account DID for login-style use cases.
OAuth 2.0 by itself is mostly an authorization framework. AT Protocol adds DID verification to make it usable for account authentication.1
| OAuth term | AT Protocol term | Role |
|---|---|---|
| Resource owner | User | Controls the account. |
| Client | App or service | Requests permission to act for the user. |
| Resource server | PDS | Accepts authorized XRPC requests. |
| Authorization server | PDS or entryway | Authenticates the user and issues tokens. |
A small PDS can be both resource server and authorization server. A larger service may put authorization in a separate entryway that serves many PDS instances.
The AT Protocol OAuth Profile
Section titled “The AT Protocol OAuth Profile”AT Protocol does not use generic OAuth with optional pieces chosen at runtime. It specifies a profile:
- Authorization Code flow only;
- PKCE with
S256; - Pushed Authorization Requests (PAR);
- DPoP-bound access tokens;
- server-issued DPoP nonces;
- client metadata discovered from the
client_idURL; - required
atprotoscope; - required
subverification against the account DID.
These choices follow the direction of OAuth 2.1 and OAuth security best current practice: avoid the implicit flow, avoid password-style grants, and do not pretend public clients can keep shared secrets.23
The Main Invariant
Section titled “The Main Invariant”The flow is correct only if these statements hold at the end:
| Binding | Question |
|---|---|
| Account binding | Did the token response name the DID the client expected? |
| Server binding | Is the authorization-server issuer authoritative for that DID’s current PDS? |
| Token binding | Are the tokens bound to the DPoP key for this client instance? |
This invariant explains most of the protocol’s ceremony. PAR protects the authorization request. PKCE protects the code exchange. DPoP protects token use. DID and issuer checks protect account authentication.
Further Reading
Section titled “Further Reading”References
Section titled “References”Footnotes
Section titled “Footnotes”-
IETF OAuth Working Group. “The OAuth 2.1 Authorization Framework”. ↩
-
Lodderstedt, Torsten, et al. RFC 9700: Best Current Practice for OAuth 2.0 Security. ↩