Add AT Protocol (Bluesky) authentication provider#102
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
startup-api | 70ddb2c | Jun 27 2026, 07:49 PM |
Implements a spec-compliant atproto OAuth login provider alongside the existing Google/Twitch/Patreon providers. atproto's flow is heavier than classic OAuth2, so this also extends the provider abstraction to support async, multi-step flows without changing existing providers' behavior. Highlights: - Full identity discovery with no hardcoded Bluesky/PDS hosts: handle -> DID (HTTPS .well-known/atproto-did, then DNS _atproto.<handle> over DoH) -> DID document (did:plc via the PLC directory, did:web via the domain) -> PDS (#atproto_pds service) -> authorization server (.well-known/oauth-protected-resource -> oauth-authorization-server). - PKCE, DPoP-bound tokens (RFC 9449, with use_dpop_nonce retry), and Pushed Authorization Requests (PAR), as required by the atproto OAuth profile. - Public OAuth client: serves its own client-metadata.json (the client_id), no client secret. Enabled via ATPROTO_ENABLED; PLC/DoH endpoints overridable via ATPROTO_PLC_URL / ATPROTO_DOH_URL. - Transient PKCE verifier + DPoP key + discovered endpoints are persisted in an encrypted, short-lived flow cookie across the redirect round-trip. - Handle-entry form shown when no identifier is supplied (standard atproto UX). - OAuthProvider gains optional authorize()/exchange()/handleExtraRoute() hooks; shared user/session creation extracted into finishLogin(). - Power-strip + profile UI: "Continue with Bluesky" button and provider icons. - Tests covering metadata, handle form, PAR+DPoP+PKCE (with nonce retry), callback token exchange/session/credential, and state-mismatch rejection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015SgFKgH1gqfP2Zx3yrnzY2
atproto is a public OAuth client with no secrets, so per the project's configuration philosophy (env holds only secrets/per-deployment values) all of its settings now live in the createStartupAPI factory config rather than env: - enabled, clientName, plcUrl, dohUrl moved onto ProviderOptions (alongside the existing Patreon-specific campaignId); enablement is providers.atproto.enabled. - isAtprotoEnabled() now takes ProviderOptions; AtprotoProvider.create reads clientName/plcUrl/dohUrl from options. - getActiveProviders(env, providerConfigs) is config-aware; providerConfigs is threaded through handleSSR and handleAdmin so the power-strip/profile/admin UIs list atproto when enabled. - Removed ATPROTO_* fields from StartupAPIEnv and wrangler.jsonc; regenerated worker-configuration.d.ts. - README + tests updated to enable atproto via the config object. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015SgFKgH1gqfP2Zx3yrnzY2
atproto has no env credentials, so the natural equivalent of "enabled because
credentials are present" is "enabled because the config key is present".
`providers: { atproto: {} }` now enables it; `enabled: false` remains as an
explicit opt-out for dynamically-built config.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015SgFKgH1gqfP2Zx3yrnzY2
sergeychernyshev
force-pushed
the
claude/atproto-auth-provider-6m2yze
branch
from
June 27, 2026 19:44
7abb5f6 to
8b6a791
Compare
Minor release for the new AT Protocol (Bluesky) authentication provider. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements a spec-compliant atproto OAuth login provider alongside the
existing Google/Twitch/Patreon providers. atproto's flow is heavier than
classic OAuth2, so this also extends the provider abstraction to support
async, multi-step flows without changing existing providers' behavior.
Highlights:
handle -> DID (HTTPS .well-known/atproto-did, then DNS _atproto.
over DoH) -> DID document (did:plc via the PLC directory, did:web via the
domain) -> PDS (#atproto_pds service) -> authorization server
(.well-known/oauth-protected-resource -> oauth-authorization-server).
Authorization Requests (PAR), as required by the atproto OAuth profile.
no client secret. Enabled via ATPROTO_ENABLED; PLC/DoH endpoints overridable
via ATPROTO_PLC_URL / ATPROTO_DOH_URL.
an encrypted, short-lived flow cookie across the redirect round-trip.
shared user/session creation extracted into finishLogin().
callback token exchange/session/credential, and state-mismatch rejection.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_015SgFKgH1gqfP2Zx3yrnzY2