atproto OAuthスコープの現状 (2025/08版)
公式発表でこの記事の内容はほぼカバーされた。以下を参照のこと。
https://github.com/bluesky-social/atproto/discussions/2656
前書き
Blueskyのaptoroリポジトリで開発されているOAuthスコープの基礎部分が先日マージされた。
現在の荒いOAuthも影響を受けており、認証画面の表示が変わったことに気付いている人もいるだろう。
あくまで基礎なのでまだ道半ばだが、開発者や利用者にも注目されているようなので、現時点の実装からざっくり情報をまとめてみた。
大体の仕様はproposal 0011で既に告知されている内容であり、新規情報としてはこれまで詳細説明を避けてきた個別のリソースの振る舞いが主となる。
「2025/08時点の」「実装から読み取った内容を」「個人の推測込みで」記載しているので、くれぐれも間に受けないように。
共通仕様
proposalの復習。
atprotoのOAuthスコープはリソース名:先頭引数値?他引数名=他引数値の形で表す。先頭引数も名前付きで定義することは可能。
proposalでは明記されていないが、名前付きは&で繋げて複数指定できる。なお、同じ引数を複数回指定することも可能で、配列として結合して解釈される。
個別のリソースはatproto仕様で定義される。詳細は後述。
スコープに対応するlexicon型としてpermissionとpermission-setが新たに定義される。
これは主にスコープを圧縮するための要素だが、実装着手したばかりなので割愛。
lexicon管理者がAPI/collectionを圧縮する用途でのみ使われ、クライアントが勝手に定義したりはできない点に注意。app.bsky.feed.*とapp.bsky.graph.*の両方を含むpermission-setを定義するには、NSIDがapp.bsky.xxxでなければならない。[^set]
[^set]: permission-setの内容更新は再認証無しで追随するため、自由な定義を許すと利用者が確認した権限が狭くても後から好き勝手できてしまう。再認証必須にすればAPIが増減する度にお伺いを立てないといけない。逆に言えばlexicon所有者は他人のappviewに悪さできる可能性があるため、XRPC APIを実装する際は採用するlexiconが信頼できるかを考慮するべき。
なお、atprotoスコープは必ず含めなければならない。これは他のリソースの仕組みとは別で、atproto用であると示すフラグのようなもの。
リソース一覧
現時点でマージ済のもののみ示す。
子アイテムはリソースが持つパラメータ。定義と同じ順序なので、先頭のものが名前を省略できる。
- repo: record操作
- collection: 対象collectionのNSID
- action: create, update, delete
- rpc: PDS外XRPC実行(プロキシ&トークン)
- lxm: 対象APIのNSID
- aud: 対象サービスのID(atproto-proxyと同じ形式)
- blob: blobアップロード
- accept: MIMEタイプ
- identity: ID情報更新(PLCサーバーへの操作)
- attr: handle, *(did:plc操作全般)
- account: アカウント情報全般(PDSへの操作)
- attr: email(アドレス取得・設定), repo(import), status(activate)
- action: read, manage
identityとaccountはまだ不安定そう。特にstatusは未実装。
permission setに関してはproposalではinclude:〜という形のスコープ構文が使われていたが、結局NSID単体になりそう?
具体的にPDSのどこで使われているかはpermissionsでコード検索すれば大体分かる。
現在使われているtransition:generic等もtransitionリソースと解釈することができる。内部では実際そんな感じで処理され、対応するリソース群にマップされる。
ユースケース別要求例
Blueskyクライアント
実用上は#4108(Permission set)を待つべき。
ごく簡単なBlueskyクライアントなら、例えば以下のようになる。文法を示すため、意図的に不揃いな書き方をした。
ちゃんとやるならrepoは全然足りないし、rpcもuploadVideoやDM周りはケアできていない。
atproto
repo:app.bsky.feed.post?action=create
repo:app.bsky.feed.post?action=delete
repo:app.bsky.feed.like?action=create&action=delete
repo?collection=app.bsky.actor.profile
rpc:*?aud=did:web:api.bsky.app%23bsky_appview
rpc:app.bsky.feed.getFeedSkeleton?lxm=com.atproto.moderation.createReport&aud=*
blob?accept=*/*
identity:handle
PDS引越し(転入)
atproto
account:repo?action=manage
account:status?action=manage
identity:*
blob:*/*
rpc:app.bsky.actor.putPreferences?aud=did:web:api.bsky.app%23bsky_appview
putPreferences(およびgetPreferences)はBluesky実装ではPDSが行うが、api.bsky.app宛のrpcが必要になる。
これは、内部処理的にはPDS_BSKY_APP_VIEW_DID宛のリクエストを横取りしている扱い^prefのため。
Discussion in the ATmosphere