| |

【初心者向け】Client Credentials Grantとは?サーバー間API連携で使う認証方式をわかりやすく解説

WebアプリやAPI開発をしていると、外部サービスのAPIを呼び出す場面があります。

たとえば、以下のようなケースです。

  • 自社のバックエンドAPIから決済サービスのAPIを呼び出す
  • バッチ処理から外部APIにアクセスする
  • マイクロサービス同士でAPI通信を行う
  • 管理用システムが別システムのAPIを定期実行する

このような「ユーザーではなく、システム自身がAPIを呼び出す」場面でよく使われるのが、OAuth 2.0 の Client Credentials Grant です。

この記事では、Client Credentials Grant について、初見の人でも分かるように図や例を交えながら解説します。

Client Credentials Grantとは?

Client Credentials Grantとは、OAuth 2.0で定義されている認可方式の一つです。簡単に言うと、サーバーやアプリケーション自身が、自分の認証情報を使ってアクセストークンを取得し、APIを呼び出す方式 です。

通常のログインではユーザーIDやパスワードを使って「人」が認証されます。一方で、Client Credentials Grantでは、ユーザーではなく クライアントアプリケーションそのもの が認証されます。

登場人物

Client Credentials Grantでは、主に以下の3つの要素が登場します。

名前役割
クライアントAPIを呼び出す側のアプリケーション
認可サーバーアクセストークンを発行するサーバー
リソースサーバー実際にAPIを提供するサーバー

たとえば、自社アプリケーションが外部の決済サービスのAPIを呼び出す場合、次のような流れになります。

自社アプリケーション
  ↓
認可サーバーからアクセストークンを取得
  ↓
取得したトークンを使って外部APIを呼び出す

全体の流れ

Client Credentials Grantの流れは非常にシンプルです。

sequenceDiagram
    participant Client as クライアントアプリ
    participant Auth as 認可サーバー
    participant API as リソースサーバー (API)

    Client->>Auth: client_id / client_secret を送信
    Auth-->>Client: アクセストークンを返却
    Client->>API: Authorization: Bearer アクセストークン
    API-->>Client: APIレスポンス

文章にすると、次のような手順です。

  1. クライアントアプリが認可サーバーに client_idclient_secret を送る。
  2. 認可サーバーがクライアントを確認する。
  3. 問題なければアクセストークンを発行する。
  4. クライアントはアクセストークンを付けてAPIを呼び出す。
  5. API側はトークンを検証し、問題なければ処理を実行する。

この方式のポイントは、ここに ユーザーのログイン画面が登場しない ことです。

なぜユーザーが登場しないのか?

Client Credentials Grantは、ユーザー操作を前提としない処理で使われます。たとえば、夜間バッチが外部APIを呼び出すケースを考えてみましょう。バッチ処理は人が画面からログインして実行するわけではありません。

夜間バッチ
  ↓
外部APIからデータ取得
  ↓
DBに保存

このような場合、ユーザーのIDやパスワードではなく、システムに発行された client_idclient_secret を使って認証します。つまり、Client Credentials Grantは、人ではなくシステム同士の信頼関係でAPIを呼び出すための方式 と考えると分かりやすいです。

client_id と client_secret とは?

Client Credentials Grantでは、クライアントアプリに対して次のような情報が発行されます。

項目説明
client_idクライアントを識別するID
client_secretクライアントだけが知っている秘密情報

イメージとしては、次のような関係です。

client_id     = アプリケーションの名前札
client_secret = アプリケーション専用のパスワード

特に client_secret は非常に重要な秘密情報です。ソースコードに直接書いたり、Gitにコミットしたりしてはいけません。環境変数やSecret Managerなど、安全な場所で管理する必要があります。

実際のリクエスト例

アクセストークンを取得するリクエストは、一般的には次のような形になります。

POST /oauth2/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)

grant_type=client_credentials

または client_idclient_secret をリクエストボディに含める場合もあります。

POST /oauth2/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=your-client-id
&client_secret=your-client-secret

成功すると、認可サーバーから次のようなJSONレスポンスが返ってきます。

{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read:items write:items"
}

この access_token を使ってAPIを呼び出します。

GET /api/items HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOi...

スコープとは?

アクセストークンには、スコープという権限情報を付けることがあります。スコープとは「このトークンで何ができるか」を表す情報です。

スコープできること
read:items商品情報の参照
write:items商品情報の登録・更新
read:usersユーザー情報の参照

Client Credentials Grantでは、システム自身に権限を与えるため、スコープ設計が重要です。参照だけで良いバッチ処理に更新権限まで付けるのは危険なので、必要最小限のスコープを付ける ようにしましょう。

Client Credentials Grantが向いているケース

Client Credentials Grantは、次のようなケースで有効です。

ケース向いている理由
サーバー間API連携ユーザー操作が不要なため
バッチ処理定期実行でAPIを呼び出せるため
マイクロサービス間通信サービス同士の認証に使いやすいため
管理系APIの自動実行システム権限で処理できるため

代表的なのは、バックエンドアプリケーションから外部APIを呼び出すケースです。

自社アプリ
  ↓
アクセストークン取得
  ↓
外部API呼び出し

向いていないケース

一方で、Client Credentials Grantが向いていないケースもあります。それはユーザーごとの権限が必要な処理 です。

例えば以下のようなケースです。

  • ログインユーザー本人の情報を取得する。
  • ユーザーAとユーザーBで見えるデータを変える。
  • ユーザーの同意を得て外部サービスにアクセスする。

このような場合は、Authorization Code Flowなど、ユーザーを前提とした認可方式を使うのが一般的です。Client Credentials Grantは、あくまで システム自身の権限でAPIを呼び出す方式 だと覚えて

Authorization Code Flowとの違い

OAuth 2.0には複数の許可方式があります。よく比較されるのがAuthorization Code Flowです。

項目Client Credentials GrantAuthorization Code Flow
主役システム・アプリケーションユーザー
ログイン画面登場しない登場する
ユーザー同意基本的に不要必要になることが多い
用途サーバー間通信、バッチWebログイン、ユーザー連携
トークンの意味アプリの権限ユーザーの権限

ざっくり分けると、

システムがAPIを呼ぶ → Client Credentials Grant
ユーザーとしてAPIを呼ぶ → Authorization Code Flow

セキュリティ上の注意点

Client Credentials Grantは便利ですが、扱いを間違えると危険です。特に client_secret の管理には注意が必要です。

client_secretをソースコードに書かない

以下のようにソースコードに直接書くのは避けるべきです。

String clientSecret = "abc123secret";

GitHubやGitLabに誤ってコミットすると、第三者に悪用される可能性があります。環境変数、Secret Manager、Kubernetes Secret、CI/CDのシークレット変数などを使って管理しましょう。

権限は最小限にする

必要以上に強いスコープを付けるのは危険です。たとえば、参照だけのバッチに更新権限を持たせる必要はありません。

OK: read:items
NG: read:items write:items admin

万が一トークンが漏洩したときの被害範囲を抑えるためにも、最小権限の考え方が大切です。

アクセストークンには有効期限を設ける

アクセストークンは永続的に使えるものではありません。有効期限を短めに設定するのが一般的です。有効期限が切れたら再度Client Credentials Grantでアクセストークンを取得します。

Spring Bootで使う場合のイメージ

Spring Bootアプリから外部APIを呼び出す場合、構成イメージは以下のようになります。

flowchart LR
    A[Spring Bootアプリ] --> B[許可サーバー]
    B --> C[アクセストークン発行]
    C --> A
    A --> D[外部API]

実装では、ざっくり次のような流れになります。

  1. 設定ファイルに許可サーバーのURLを定義する
  2. client_idclient_secret を環境変数などで管理する
  3. API呼び出し前にアクセストークンを取得する
  4. Authorization: Bearer ヘッダーを付けて外部APIを呼び出す

よくある勘違い

「Client Credentials Grantはログイン機能で使うもの」

ログイン機能には基本的に使いません。Client Credentials Grantは、ユーザーではなくアプリケーション自身を認証する方式です。ユーザーのログインやユーザーごとの権限管理が必要な場合は、Authorization Code Flowなど別の方式を検討します。

「client_secretがあればずっとAPIを呼べる」

強言には、client_secret でアクセストークンを取得し、そのアクセストークンでAPIを呼びます。API呼び出し時に毎回 client_secret を送るのではなく、基本的には取得したアクセストークンを使います。

「アクセストークンはDBに保存すべき」

多くの場合、長期間DBに保存する必要はありません。アクセストークンには有効期限があるため、アプリケーション内でキャッシュし、期限が近づいたら再取得する設計が一般的です。ただし、サービスの仕様やシステム構成によって変わるため、許可サーバー側の仕様に合わせる必要があります。

まとめ

Client Credentials Grantは、OAuth 2.0で使われる許可方式の一つです。

ポイントを整理すると、以下の通りです。

  • ユーザーではなく、アプリケーション自身が認証される
  • サーバー間API連携やバッチ処理に向いている
  • client_idclient_secret を使ってアクセストークンを取得する
  • API呼び出し時は Authorization: Bearer ヘッダーを使う
  • ユーザーごとの権限が必要な処理には向いていない
  • client_secret の管理とスコープ設計が重要

Client Credentials Grantは、システム間連携では非常によく使われる方式です。「ユーザーがログインするための仕組み」ではなく、アプリケーションが安全にAPIを呼び出すための仕組み と理解すると、かなりスッキリします。おきましょう。

是非フォローしてください

最新の情報をお伝えします

類似投稿