atproto-oauth

Installation
SKILL.md

AT Protocol OAuth

Guidance for implementing the AT Protocol OAuth 2.1 profile: PAR, DPoP-bound tokens, PKCE, client metadata documents, scopes/permission sets, identity verification, and session/security hardening in TypeScript.

Protocol Essentials

AT Proto OAuth is OAuth 2.1 with no opt-outs on the following:

  • PKCE S256 is mandatory. code_challenge_method=S256 only — never plain. Verifier is 43–128 random chars from [A-Z a-z 0-9 - . _ ~].
  • PAR (Pushed Authorization Request) is mandatory. The browser never sees the real authorization parameters — they're POSTed server-to-server to pushed_authorization_request_endpoint first, returning a request_uri that's the only thing placed on the authorize redirect.
  • DPoP-bound tokens are mandatory. Every request to the authorization server (AS) and resource server (PDS) carries a signed DPoP proof JWT (RFC 9449). dpop_bound_access_tokens: true is required in client metadata. There is no bearer-only mode.
  • client_id is a URL, not an opaque string. It resolves to a JSON client metadata document that the AS fetches at the start of every flow — this is AT Proto's dynamic client registration mechanism, replacing static pre-registration. The exact same client_id string must appear byte-for-byte across metadata publication, PAR, authorize, and token/refresh calls — any drift invalidates the grant.
  • No client_secret, ever. Confidential clients (anything with a server-side component) authenticate to the token endpoint with a private_key_jwt client assertion (JWT signed ES256, referencing a key published in the client's jwks/jwks_uri). Public clients (pure browser SPA, native apps with no backend) authenticate with DPoP proof possession alone — token_endpoint_auth_method: none.

Session lifetime differs by client type: confidential clients get refresh tokens valid up to 180 days (session itself unlimited, rotates keys periodically); public clients are capped at 14 days total, silently, until day 15 when refresh suddenly starts failing with invalid_grant.

The End-to-End Flow

Installs
1
GitHub Stars
1
First Seen
14 days ago
atproto-oauth — hypercerts-org/skills