OAuth 2.0スコープ管理のベストプラクティス

きめ細かいアクセス制御のためのOAuth 2.0スコープの設計、リクエスト、検証方法。人気APIの一般的なスコープパターンを含みます。

Security

詳細な説明

OAuth 2.0スコープ管理

スコープはクライアントがリクエストできるアクセスの境界を定義します。OAuth 2.0アクセストークンが何をできるかを制限する主要なメカニズムです。適切なスコープ設計はセキュリティ(最小権限の原則)とユーザーの信頼(ユーザーが何を付与するか正確に確認できる)に不可欠です。

スコープの仕組み

  1. クライアントがスコープをリクエスト: 認可リクエストでscope=read:user write:repos
  2. ユーザーがレビューして同意: リクエストされた権限に対して
  3. サーバーがより少ないスコープを付与する場合がある:(多くなることはない)
  4. トークンに付与されたスコープが含まれる: レスポンスで"scope": "read:user write:repos"
  5. リソースサーバーが強制: エンドポイントごとのスコープ要件

一般的なスコープパターン

フラットスコープ(シンプル):

read write delete admin

リソースベーススコープ(GitHubスタイル):

read:user write:repos delete:gists admin:org

階層的スコープ(Googleスタイル):

https://www.googleapis.com/auth/gmail.readonly
https://www.googleapis.com/auth/gmail.send
https://www.googleapis.com/auth/calendar.events

OpenID Connect標準スコープ:

スコープ 含まれるクレーム
openid サブジェクト識別子(OIDCに必須)
profile name, family_name, given_name, pictureなど
email email, email_verified
address 郵送先住所
phone phone_number, phone_number_verified

リソースサーバーでのスコープ検証

function requireScope(requiredScope) {
  return (req, res, next) => {
    const tokenScopes = req.token.scope.split(" ");
    if (!tokenScopes.includes(requiredScope)) {
      return res.status(403).json({
        error: "insufficient_scope",
        error_description: `必要なスコープ: ${requiredScope}`,
      });
    }
    next();
  };
}

// 使用方法
app.get("/api/user", requireScope("read:user"), getUserHandler);
app.post("/api/repos", requireScope("write:repos"), createRepoHandler);

ベストプラクティス

  • 実際に必要なスコープのみをリクエスト(最小権限)
  • 広範なスコープよりも詳細なスコープを使用(adminよりもread:userを優先)
  • APIリファレンスで利用可能なすべてのスコープを文書化
  • スコープのダウングレードを適切に処理(サーバーがより少ないスコープを付与する場合がある)
  • 必要に応じて追加のスコープを段階的に再リクエスト(プログレッシブコンセント)

ユースケース

OAuth 2.0を使用するAPIの設計。APIのリソースと操作にマッピングする意味のあるスコープを定義し、リソースサーバーにアクセス制御を強制するスコープチェックミドルウェアを実装する必要があります。

試してみる — OAuth 2.0 Flow Visualizer

フルツールを開く