Overview
Bluesky’s OAuth is based on the AT Protocol and differs significantly from standard Socialite providers such as GitHub or Google.Differences from standard OAuth
Authentication flow
Installation and configuration
Create a private key
Generate a private key. No Bluesky account registration is required..env file.
For Bluesky, you don’t need to register a
client_id or client_secret. Setting the private key is the only required step.Default OAuth scopes
The package is configured with default OAuth scopes to support three main use cases:- Socialite Login —
atproto,account:email, andinclude:app.bsky.authViewAllenable user authentication and email access - Posting —
include:app.bsky.authCreatePostsandblob:*/*allow creating posts and uploading images/videos - DM Notifications —
rpc:chat.bsky.convo.sendMessageandrpc:chat.bsky.convo.getConvoForMembersenable sending direct messages for notifications
BLUESKY_OAUTH_SCOPE environment variable:
Local development
By default,http://localhost and http://127.0.0.1:8000/ are preconfigured, so no additional .env settings are needed for local development.
Production
If the route namedbluesky.oauth.redirect exists, no .env configuration is needed. Set it only if you have changed the default route name.
Route setup
Usebluesky.oauth.redirect as the callback route name — the package uses this name internally.
Handling callbacks in local development
During local development, the callback URL returned by Bluesky is fixed tohttp://127.0.0.1:8000/. Redirect it at the route level.
Controller implementation
User information (OAuthSession)
Key methods available on theOAuthSession retrieved from $user->session.
Use
toArray() to inspect all properties.
Database setup
Add Bluesky-specific columns to theusers table. The DID is the unique identifier for a Bluesky user.
Reusing the OAuthSession
Use the OAuthSession stored in the session to call APIs.Automatic token refresh
Refresh tokens can only be used once, so you must save the updated token after each refresh. Use theOAuthSessionUpdated event.
OAuthSessionRefreshing event fires when a refresh starts. Clear the refresh token from the database here, since it becomes invalid at this point.
WithBluesky trait
Add theWithBluesky trait to your User model and implement tokenForBluesky() to get an authenticated Bluesky client via $user->bluesky().
Customizing client-metadata
The package automatically registersbluesky.oauth.client-metadata and bluesky.oauth.jwks routes. Changes are rarely needed, but you can customize them with OAuthConfig.
Unauthenticated behavior
IfOAuthSession is null or has no refresh token, an Unauthenticated exception is thrown and the user is redirected to the login route.
Source: docs/socialite.md