システムとしてAPIを構築・提供する際、APIを呼び出すクライアントをどのように認証するか「クライアント認証方式」を考える必要があります。
クライアント認証とはOAuth 2.0 / OpenID Connect(OIDC)でアクセストークンを取得するときに、クライアント自身を認証する方式 のことです。
クライアント認証方式にはさまざまな方式があり、APIの公開範囲や相手先との信頼関係、セキュリティなどさまざまな観点からどの方式で認証すべきか検討する必要があります。
client_secret_basicprivate_key_jwttls_client_authself_signed_tls_client_auth
本記事では、各クライアント認証方式の概要について整理し、提供するAPIについて適切な認証方式を選択できるようまとめます。
1. 「クライアント認証」と「API認可」の概要
まずは前提となる「クライアント認証」と「API認可」の違いを説明します。
OAuth 2.0 のクライアントがAPIを呼び出す典型的な流れは、次のようになります。
ここで役割を分けると、次の通りです。
| 処理 | 確認すること | 代表例 |
|---|---|---|
| クライアント認証 | トークンを要求しているクライアントは正規のクライアントか |
client_secret_basic, private_key_jwt, mTLS |
| API認可 | このアクセストークンでAPI操作を許可してよいか | scope、audience、roleなどの検証 |
今回考えるのはAPIの呼び出し元であるクライアントをどのように認証するかであるクライアント認証方式についてそれぞれの違いや向いている用途を整理したいと思います。
2. クライアント認証方式の種類
OAuthにおけるトークンエンドポイントのクライアント認証方式には下記のような種類があります。
| 方式名 | 意味 | 主な定義元 |
|---|---|---|
none |
クライアント認証なし | RFC 7591 / OAuth Public Client |
client_secret_post |
POST bodyでクライアントシークレットを送信 | RFC 6749、RFC 7591 |
client_secret_basic |
HTTP Basic認証でクライアントシークレットを送信 | RFC 6749、RFC 7591 |
client_secret_jwt |
共有シークレットを鍵にした署名JWTで認証 | OpenID Connect Core 1.0 |
private_key_jwt |
秘密鍵で署名したJWTで認証 | OpenID Connect Core 1.0、RFC 7523 |
tls_client_auth |
PKIベースのmTLSで認証 | RFC 8705 |
self_signed_tls_client_auth |
自己署名証明書ベースのmTLSで認証 | RFC 8705 |
またそれぞれの方式ごとの特徴は下記となります。
| 方式 | クライアントが保持するもの | 特徴 | 想定ケース |
|---|---|---|---|
none |
認証用の秘密情報なし | Public Client向け。通常はPKCEと併用 | SPA、モバイルアプリ |
client_secret_basic |
共有シークレット | シンプルで広く利用される | 通常のサーバーサイドアプリ |
client_secret_post |
共有シークレット | シークレットをリクエストbodyに含める | Basicを利用できない制約がある場合 |
client_secret_jwt |
共有シークレット | シークレットをHMAC署名鍵として使う | JWT assertionを利用したい場合 |
private_key_jwt |
秘密鍵 | 秘密鍵を送らず、公開鍵で検証可能 | BFF、M2M、高セキュリティAPI連携 |
tls_client_auth |
CA発行のクライアント証明書と秘密鍵 | PKI/CAによる証明書信頼モデル | 企業間・金融API |
self_signed_tls_client_auth |
自己署名証明書と秘密鍵 | 登録済み公開鍵・証明書を直接信頼 | 限定されたM2M連携 |
3. none:クライアント認証なし
none は、SPAやモバイルアプリなど、クライアントシークレットを安全に保持できない Public Client が使う方式です。
クライアント認証は行いませんが、認可コードフローでは通常 PKCE(RFC 7636) を利用して、認可コードの横取り対策を行います。
PKCEはクライアント認証そのものではなく、認可コード横取り対策の仕組みです。
4. client_secret_basic:Basic認証でシークレットを送る
client_secret_basic は、client_id と client_secret を HTTP Basic 認証で送る方式です。
POST /oauth2/token HTTP/1.1
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
シンプルで広くサポートされている一方、クライアントと認可サーバーが同じシークレットを保持するため、シークレットの保管・ローテーションが重要です。
5. client_secret_post:POST bodyでシークレットを送る
client_secret_post は、client_id と client_secret をリクエストbodyに含める方式です。
POST /oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=batch-client&
client_secret=secret-value
Authorizationヘッダーを設定できない、または、プロキシやゲートウェイでAuthorizationヘッダーが削除されてしまうようなHTTP Basic認証を扱えない環境では候補になりますが、シークレット値そのものを送る点はclient_secret_basic と共通です。
6. client_secret_jwt:共有シークレットでJWTに署名する
client_secret_jwt は、クライアントシークレットを直接送る代わりに、共有シークレットを使ってJWTへHMAC署名し、そのJWTをクライアント認証に使う方式です。
HMAC署名とは、共有している秘密鍵(secret)とハッシュ関数を使って、データが改ざんされていないこと・正しい相手が作成したことを確認する仕組みのこと
JWT assertionの送信例は次のようになります。
POST /oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=batch-client&
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&
client_assertion=eyJ...
client_secret 自体を通信で送らない点は特徴ですが、クライアントと認可サーバーが共有シークレットを持つ信頼モデルは変わりません。
7. private_key_jwt:秘密鍵でJWTに署名する
private_key_jwt は、クライアントが自身の秘密鍵で署名したJWTを client_assertion として送る方式です。
認可サーバーは、事前に登録された公開鍵やJWKSを使って署名を検証します。
JWKS は JSON Web Key Set の略で、JWTなどの署名を検証するための公開鍵を、JSON形式で複数まとめて公開する仕組み
client_secret のような共有秘密を認可サーバーに保持させず、検証用の公開鍵のみを登録できる点が特徴です。
JWT assertionの送信例は次のようになります。
{
"iss": "batch-client",
"sub": "batch-client",
"aud": "https://auth.example.com/oauth2/token",
"iat": 1770000000,
"exp": 1770000300,
"jti": "b72865d5-68b6-4c62-a99a-6dde7108ee62"
}
代表的なクレームの意味は以下です。
| クレーム | 意味 |
|---|---|
iss |
JWTの発行者。通常は client_id
|
sub |
認証対象。通常は client_id
|
aud |
JWTの宛先。通常はトークンエンドポイント |
iat |
発行時刻 |
exp |
有効期限 |
jti |
JWTの一意識別子。リプレイ対策で利用可能 |
8. tls_client_auth:PKIベースのmTLS
tls_client_auth は、認可サーバーが信頼するCAから発行されたクライアント証明書を利用する方式です。
認可サーバーは、主に以下を確認します。
- 証明書チェーンが信頼できるCAにつながること
- クライアントに登録された Subject DN や SAN 等の値と、提示された証明書が対応すること
この方式は、外部企業とのAPI連携や金融系APIなど証明書管理・失効管理を求められる環境、多数クライアントをPKI運用で統制したい場合に向いています。
mTLSとは何か
mTLS の m は mutual(相互) です。
通常のTLSでは、クライアントが主にサーバー証明書を検証します。一方、mTLSでは、サーバーもクライアント証明書を検証します。
OAuth 2.0 で mTLS を使う場合、RFC 8705 は次の2種類のクライアント認証方式を定義しています。
tls_client_authself_signed_tls_client_auth
9. self_signed_tls_client_auth:自己署名証明書ベースのmTLS
self_signed_tls_client_auth は、自己署名クライアント証明書を利用する方式です。
認可サーバーは、CAの証明書チェーンを信頼の根拠にするのではなく、クライアントに紐づけて事前登録された証明書または公開鍵と、接続時に提示された証明書を照合します。
この方式は、管理対象クライアントが少ないM2M連携や特定パートナーとの限定されたAPI連携、PKI運用を設けず、公開鍵の事前登録で管理できる構成に向いています。
tls_client_auth と self_signed_tls_client_auth の違い
self_signed_tls_client_auth は「自己署名だから即座に危険」という意味ではありません。
何を信頼の根拠にするかが違う方式です。ただしクライアント数が増えると、証明書の登録・更新・失効の個別管理が重くなりやすい点には注意が必要です。
| 観点 | tls_client_auth |
self_signed_tls_client_auth |
|---|---|---|
| 証明書 | CA発行証明書 | 自己署名証明書 |
| 信頼の根拠 | 信頼済みCA・PKI | 事前登録した証明書または公開鍵 |
| 照合方法 | 証明書チェーン検証 + Subject DN / SAN 等 | 登録済み証明書・公開鍵との一致 |
| 失効・更新管理 | CA/PKI運用に寄せられる | クライアント単位で登録情報を更新 |
| 適した規模 | 多社・大規模・統制重視 | 小規模・限定連携 |
まとめ
API連携を設計する際は、「アクセストークンをどう使ってAPIを認可するか」だけでなく、そのアクセストークンを取得するクライアントをどう認証するか まで分けて考えると、方式選定が整理しやすくなります。
参考になりましたら、ぜひ「いいね」をお願いします。
参考仕様・ドキュメント
- IANA: OAuth Parameters - OAuth Token Endpoint Authentication Methods
- RFC 6749: The OAuth 2.0 Authorization Framework
- RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol
- RFC 8414: OAuth 2.0 Authorization Server Metadata
- RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
- RFC 7515: JSON Web Signature (JWS)
- OpenID Connect Core 1.0 incorporating errata set 2
- OpenID Connect Discovery 1.0 incorporating errata set 2
- RFC 7636: Proof Key for Code Exchange by OAuth Public Clients
- RFC 8705: OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens
- AWS KMS API Reference: Sign
- AWS KMS Developer Guide: Asymmetric keys in AWS KMS
