Bluesky social oauth scope "Bad token scope" - Stack Overflow

I'm trying to build an app that integrates with bsky's OAuth and API. Using the below the doc

I'm trying to build an app that integrates with bsky's OAuth and API. Using the below the document using the "Browser App" option. /docs/advanced-guides/oauth-client

I'm requesting the following scopes, which (from /blog/oauth-atproto) are all of the scopes supported by Bluesky

scope: 'atproto transition:generic transition:chat.bsky

atproto = required transition:generic = the same level of permissions as an App Password transition:chat.bsky = adds access to the chat.bsky.* which isn't related to this question

During OAuth, bsky.social shows the follow permissions being granted:

  • Uniquely identify you
  • Access your chat messages
  • Access your account data (except chat messages)

Once I get the JWT access token I can make requests to get records no problem:

  • /xrpc/com.atproto.repo.listRecords

But the moment I try and write to the API using the JWT I get the following response:

{
    "error": "InvalidToken",
    "message": "Bad token scope"
}

from endpoints com.atproto.repo.createRecord or com.atproto.repo.putRecord

I'm not sure why this occurs considering I've got permission to all scopes. Authenticating with com.atproto.server.createSession and using the JWT from that response works fine, but I can't use this endpoint for customers as it requires them passing the username and password.

I'm trying to build an app that integrates with bsky's OAuth and API. Using the below the document using the "Browser App" option. https://docs.bsky.app/docs/advanced-guides/oauth-client

I'm requesting the following scopes, which (from https://docs.bsky.app/blog/oauth-atproto) are all of the scopes supported by Bluesky

scope: 'atproto transition:generic transition:chat.bsky

atproto = required transition:generic = the same level of permissions as an App Password transition:chat.bsky = adds access to the chat.bsky.* which isn't related to this question

During OAuth, bsky.social shows the follow permissions being granted:

  • Uniquely identify you
  • Access your chat messages
  • Access your account data (except chat messages)

Once I get the JWT access token I can make requests to get records no problem:

  • https://bsky.social/xrpc/com.atproto.repo.listRecords

But the moment I try and write to the API using the JWT I get the following response:

{
    "error": "InvalidToken",
    "message": "Bad token scope"
}

from endpoints com.atproto.repo.createRecord or com.atproto.repo.putRecord

I'm not sure why this occurs considering I've got permission to all scopes. Authenticating with com.atproto.server.createSession and using the JWT from that response works fine, but I can't use this endpoint for customers as it requires them passing the username and password.

Share Improve this question edited 10 hours ago marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 24 at 0:51 BobbyZHolmesBobbyZHolmes 7357 silver badges12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I've been fighting my way through this same set of issues. I'm not all the way there yet, but here's a summary of what I've found so far. Depending on what language you use, there are some working examples out there. Two that helped me were: https://github/bluesky-social/cookbook/tree/main/python-oauth-web-app and https://pkg.go.dev/github/potproject/atproto-oauth2-go-example.

Implementing OAuth with Bluesky API: The Missing Manual

Overview

Authenticating with Bluesky using OAuth is significantly more complex than traditional OAuth implementations due to Bluesky's use of advanced security mechanisms like DPoP (Demonstrating Proof of Possession) and their multi-tiered API architecture. This guide outlines the key requirements and steps for successfully implementing OAuth authentication with Bluesky.

Authentication Architecture Understanding

Bluesky's API consists of two main components:

  1. Personal Data Server (PDS) - Stores user data and provides endpoints for interacting with a user's own content
  2. AppView API - Provides endpoints for viewing and interacting with other users' content

Important: OAuth tokens can only be used with PDS endpoints, not with AppView endpoints.

Key Requirements

1. OAuth Flow Requirements

  • You must implement the Authorization Code flow
  • PKCE (Proof Key for Code Exchange) is required
  • Client metadata must be publicly available at a HTTPS URL
  • PAR (Pushed Authorization Requests) is required

2. DPoP Authentication

  • All requests must use DPoP for proof of possession
  • The Authorization header format is Authorization: DPoP <token> (not Bearer <token>)
  • DPoP tokens must be generated with the ES256 algorithm (P-256 curve)
  • Each DPoP token must include:
    • A unique JTI (JWT ID)
    • The HTTP method (htm) for the request
    • The exact target URL (htu) for the request
    • The current server-provided nonce after the first request

3. API Access Limitations

  • OAuth tokens only work with PDS endpoints (/xrpc/com.atproto.*)
  • OAuth tokens do not work with AppView endpoints (/xrpc/app.bsky.*)
  • To access user profile info, use the PDS endpoint (/xrpc/com.atproto.repo.getRecord) with appropriate parameters

Implementation Steps

1. Client Registration

Create a client metadata JSON file available at a public HTTPS URL:

{
  "client_id": "https://your-app/.well-known/bluesky-oauth.json",
  "application_type": "web",
  "client_name": "Your App Name",
  "client_uri": "https://your-app",
  "dpop_bound_access_tokens": true,
  "require_pkce": true,
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "redirect_uris": [
    "https://your-app/auth/bluesky/callback"
  ],
  "response_types": [
    "code"
  ],
  "scope": "atproto transition:generic transition:chat.bsky",
  "token_endpoint_auth_method": "none"
}

2. Authorization Request

  1. Generate a PKCE code verifier and challenge
  2. Redirect user to Bluesky's authorization URL with:
    • client_id (URL to your metadata JSON)
    • redirect_uri
    • response_type = "code"
    • scope = "atproto transition:generic transition:chat.bsky"
    • code_challenge and code_challenge_method = "S256"
    • state (security token)

3. Token Exchange with DPoP

  1. Generate a P-256 key pair for DPoP
  2. Create a DPoP token for the token exchange request with the token endpoint URL
  3. Exchange the authorization code for tokens:
    • grant_type = "authorization_code"
    • code = received code from authorization
    • redirect_uri = same as in authorization request
    • code_verifier = PKCE verifier from step 2
    • client_id = URL to your metadata JSON
  4. Include DPoP header with the DPoP token
  5. Handle DPoP nonce from the server response for subsequent requests

4. Making API Requests

  1. Generate a new DPoP token for each request
  2. Use Authorization: DPoP <access_token> in the header
  3. Include the DPoP token in the DPoP header
  4. Include the server-provided nonce in subsequent DPoP tokens
  5. Only use PDS endpoints (those starting with /xrpc/com.atproto.*)
  6. Handle responses properly, including new nonces

5. Profile Information Access

To get user profile info:

GET /xrpc/com.atproto.repo.getRecord?repo=<user-did>&collection=app.bsky.actor.profile&rkey=self

The response structure is complex, with nested objects:

{
  "uri": "at://did:plc:abc123/app.bsky.actor.profile/self",
  "cid": "bafyreiabc123...",
  "value": {
    "$type": "app.bsky.actor.profile",
    "displayName": "User Name",
    "description": "Bio text",
    "avatar": {
      "$type": "blob",
      "ref": {
        "$link": "bafkreiabc123..."
      },
      "mimeType": "image/jpeg",
      "size": 12345
    }
  }
}

Common Pitfalls and Solutions

  1. "Bad token scope" error:

    • Ensure you're using DPoP (not Bearer) in the Authorization header
    • Make sure your DPoP token is signed with ES256
    • Verify you're accessing PDS endpoints, not AppView endpoints
  2. DPoP nonce issues:

    • Always store and reuse the most recent nonce from the server
    • Create a new DPoP token for each request
    • Handle the nonce retry flow correctly
  3. Avatar image access:

    • Avatar URLs must be constructed from the response:

      <endpoint>/xrpc/com.atproto.sync.getBlob?did=<user-did>&cid=<avatar-cid>
      
  4. Handle retrieval:

    • The getSession endpoint doesn't work with OAuth
    • Extract handle from other responses or store it when initially retrieved

Limitations

The OAuth implementation in Bluesky currently has these limitations:

  1. OAuth tokens can only access PDS endpoints (not AppView endpoints)
  2. Some operations will require using other authentication methods
  3. OAuth implementation differs from typical OAuth flows by requiring DPoP

For full API access, you may need to implement a hybrid approach using both OAuth for PDS endpoints and other authentication methods for AppView endpoints.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744264438a4565797.html

相关推荐

  • Bluesky social oauth scope &quot;Bad token scope&quot; - Stack Overflow

    I'm trying to build an app that integrates with bsky's OAuth and API. Using the below the doc

    8天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信