Skip to content

Authentication

Open Social supports two authentication methods:

The web app uses AT Protocol OAuth for user authentication:

  1. User clicks “Login” and enters their Bluesky handle
  2. Redirected to their PDS for authorization
  3. PDS shows the specific permissions Open Social is requesting
  4. Callback completes the session (stored in sid cookie)
  5. Session agent is used for all authenticated requests

Open Social requests granular permissions following the AT Protocol permission spec, rather than full account access:

ScopePurpose
atprotoRequired base scope for all AT Proto OAuth flows
repo:community.opensocial.membershipWrite membership records to the user’s own repo (join/leave communities)
transition:genericLegacy full-access fallback for PDS compatibility during the transition to granular scopes

Open Social only writes community.opensocial.membership records to your personal repository. All other data (profiles, admin lists, membership proofs, community records) is managed by the community’s own AT Protocol account — not your personal account.

The transition:generic scope is included temporarily for backward compatibility with PDS implementations that don’t yet support granular scopes. It will be removed once granular scope support is widespread.

Third-party apps integrating with Open Social can request the bundled permission set instead of enumerating individual scopes:

include:community.opensocial.authBasic

This grants the same repo:community.opensocial.membership write permission in a single scope declaration. See the lexicon reference for the full permission set definition.

EndpointDescription
POST /loginStart OAuth flow (body: input=handle)
POST /logoutEnd session
GET /users/meGet authenticated user
GET /oauth-client-metadata.jsonOAuth client metadata
GET /.well-known/jwks.jsonPublic key set

For server-to-server or app integrations:

  1. Register an app (requires OAuth session first):
    POST /api/v1/apps/register
    { "name": "My App", "domain": "myapp.example.com" }
  2. Store the returned apiKey securely
  3. Include it in all API requests:
    X-Api-Key: osc_abc123...
ActionEndpoint
Register appPOST /api/v1/apps/register (OAuth)
List appsGET /api/v1/apps (OAuth)
Rotate keyPOST /api/v1/apps/:appId/rotate-key (OAuth)
Verify keyPOST /api/v1/apps/verify (API Key)
DeactivateDELETE /api/v1/apps/:appId (OAuth)

API keys follow the format: osc_ followed by 64 hex characters. Keys are stored as SHA-256 hashes — the plaintext is only returned once at creation.

API Key routes are rate limited to 100 requests per minute per app by default. Auth endpoints have stricter limits (20 per 15 minutes). Custom limits can be configured per app.

State-changing requests from browser sessions require CSRF tokens. API Key requests are exempt (no CSRF risk for server-to-server calls).

The token flow:

  1. Read the csrf-token cookie value
  2. Include it as the x-csrf-token header on POST/PUT/DELETE requests