Microsoft Entra External IDでOAuthのClient credentialsを使えるようになると、B2Cやパートナー向けアプリの設計は大きく変わります。結論から言えば、ユーザーのサインインを伴わないバックエンド処理、パートナー間API連携、バッチ処理、イベント駆動のシステム連携を、ユーザーIDの“なりすまし”ではなくアプリ自身のIDで安全に扱えるようになります。MicrosoftはEntraの2026年3月更新で、Microsoft Entra External IDにおけるClient credentialsの一般提供を案内しており、M2M認証にはM2M Premiumアドオンが必要と明記しています。(Microsoft Learn)
Identity developersやplatform architectsにとって重要なのは、「ログイン機能が増えた」という話ではありません。B2C/CIAM基盤の中で、顧客・パートナー・バックエンドサービスを分けて設計しやすくなったことです。特に、パートナー企業のシステムが自社APIへ直接アクセスするSaaS連携、注文・請求・在庫同期などの非対話処理、顧客アプリの裏側で動くジョブの認可モデルを整理したいチームにとって、Microsoft Entra External ID Client credentialsは優先して検討すべきOAuth設計パターンです。
Microsoft Entra External IDでClient credentials対応が意味すること
Client credentials flowは、OAuth 2.0の「アプリケーション自身が認証する」フローです。Microsoftのドキュメントでは、Webサービスや機密クライアントがユーザーを偽装せず、自分自身の資格情報で別のWebサービスを呼び出す仕組みとして説明されています。バックグラウンドで動くサーバー間通信、デーモン、サービスアカウント型の処理で使われます。(Microsoft Learn)
これまでB2C/CIAMの設計では、どうしても「人間のサインイン」が中心になりがちでした。顧客がログインして注文履歴を見る、パートナー担当者がポータルに入ってデータを更新する、といった画面中心の設計です。しかし実際のB2Cやパートナー連携では、次のような「人が画面を操作していないのにAPIを呼ぶ」処理が頻繁にあります。
| シーン | Client credentialsが効く理由 |
|---|---|
| パートナー企業の受発注システムが自社APIへ注文データを送る | パートナーのシステムをアプリIDとして識別し、ユーザーに依存しない認可ができる |
| 夜間バッチで会員ステータスや請求情報を同期する | 特定の管理者ユーザーの資格情報を使わず、ジョブ専用の権限を付与できる |
| ECサイトのバックエンドが在庫・配送・CRM APIを呼ぶ | サービスごとに最小権限のアプリロールを割り当てられる |
| SaaS連携で複数テナントや複数パートナーを扱う | パートナー単位、用途単位でクライアントアプリを分離しやすい |
| イベント駆動でWebhook受信後に内部APIを呼び出す | ユーザーセッションがない処理でも標準的なBearerトークンで保護できる |
設計上のポイントは、「誰が操作したか」ではなく「どのアプリケーションが、どの権限でAPIを呼んだか」を中心に考えることです。
B2Cアプリ設計で解放されるもの
Microsoft Entra External IDは、コンシューマーやビジネス顧客向けアプリのCIAM基盤として利用でき、外部構成のテナントで従業員とは別にアプリとユーザーアカウントを管理できます。サインアップ手順、サインイン方法、ブランド設定などを外部向けに構成できる点が特徴です。(Microsoft Learn)
Client credentials対応により、B2Cアプリは「顧客のログイン体験」と「サービス間の業務処理」を同じID基盤の考え方で整理しやすくなります。
顧客操作とバックエンド処理を分離できる
たとえば、ECサイトで顧客が注文を確定する場面を考えます。
顧客がブラウザやモバイルアプリでサインインする処理には、OpenID ConnectやAuthorization Code Flowを使います。一方で、注文確定後にバックエンドが配送API、在庫API、請求APIを呼び出す処理は、顧客のアクセストークンをそのまま使うべきとは限りません。
配送ラベル作成や請求確定は、顧客本人の権限というより、ECサービスの業務権限として実行されることが多いためです。この場合、バックエンドサービスがClient credentialsでアクセストークンを取得し、Order.ProcessやShipping.Createのようなアプリケーション権限でAPIを呼ぶ設計が自然です。
“疑似ユーザー”を作らずに済む
実務では、過去の制約から「[email protected]」のような管理用ユーザーを作り、そのユーザーのIDでバッチやAPI連携を動かしているケースがあります。これは監査、権限管理、パスワード管理の面で問題を生みやすい設計です。
Client credentialsを使えば、バックエンド処理をユーザーではなくアプリケーションとして表現できます。アクセス許可は管理者がアプリケーション自体に直接付与し、API側はユーザーが関与しない前提でアプリの権限を検証します。(Microsoft Learn)
MAU中心のB2C設計とM2Mの課金観点を分けて考えられる
注意点として、Microsoft Entra External IDでM2M認証を構成する場合はM2M Premiumアドオンが必要です。Microsoftは、コスト影響と社内ガバナンス・ライセンス要件を確認するよう案内しています。(Microsoft Learn)
つまり、B2Cの顧客ログイン設計とM2M連携設計は、同じExternal ID上で扱えても、利用量・課金・ガバナンスの管理単位は分けて検討すべきです。特に大量のバッチや頻繁なトークン取得を行う設計では、認証リクエストの頻度、キャッシュ、リトライ制御を初期段階から見積もる必要があります。
パートナーアプリケーション設計で解放されるもの
パートナー連携では、Client credentialsの価値がさらに明確になります。パートナー企業の担当者がポータルにログインするケースだけでなく、パートナーの業務システムが自社APIへ直接アクセスするケースが多いからです。
パートナーごとにアプリIDを分けられる
パートナーA、パートナーB、代理店Cが同じAPIを呼ぶ場合、1つの共通クライアントを全社で使い回す設計は避けるべきです。漏えい時の影響範囲が広く、監査ログから呼び出し元を特定しにくくなります。
推奨しやすい設計は、次のようにクライアントアプリを分けることです。
| 設計単位 | 例 | メリット |
|---|---|---|
| パートナー単位 | partner-a-order-client | 漏えい・停止・ローテーションの影響をパートナー単位に限定できる |
| 用途単位 | partner-a-readonly-client、partner-a-write-client | 読み取り専用と更新用を分け、最小権限にしやすい |
| 環境単位 | partner-a-prod-client、partner-a-test-client | 本番・検証の資格情報混在を防ぎやすい |
| 地域・ブランド単位 | partner-eu-client、partner-jp-client | データ境界や運用責任を分けやすい |
この分割により、「どのパートナーの、どの用途の、どの環境から呼ばれたAPIなのか」をトークンとログから追跡しやすくなります。
アプリロールでAPI権限を表現できる
Microsoft identity platformでは、Client credentialsのようなApp-onlyアクセスでは、委任スコープではなくアプリロール、つまりApplication permissionsを使います。ユーザーが存在しないため、ユーザーに代わるDelegated permissionsではなく、アプリケーションに直接許可された権限をAPI側で確認する設計になります。(Microsoft Learn)
たとえば、パートナー向け注文APIなら、次のようなアプリロールを設計できます。
| アプリロール | 用途 | 付与対象の例 |
|---|---|---|
Orders.Read | 注文照会 | 物流パートナー、サポート連携 |
Orders.Submit | 注文登録 | 代理店システム |
Orders.Cancel | 注文キャンセル | 限定されたパートナーのみ |
Inventory.Read | 在庫参照 | 販売パートナー |
Invoice.Read | 請求参照 | 会計・精算連携 |
アプリロールはアプリ登録で定義し、別アプリケーションのサービスプリンシパルにも割り当てられます。Microsoftの説明では、サービスプリンシパルをグループに追加して、そのグループにアプリロールを割り当てても、発行されるトークンにrolesクレームは追加されません。パートナー連携では、期待したrolesが出ない事故を避けるため、クライアントアプリへ直接アプリロールを割り当てる設計を優先してください。(Microsoft Learn)
Client credentialsを使うべきケース、使わないケース
Client credentialsは便利ですが、万能ではありません。設計判断を誤ると、ユーザー単位の監査や同意が必要な処理までアプリ権限で実行してしまいます。
| 判断軸 | Client credentialsが向く | 別フローを検討すべき |
|---|---|---|
| ユーザー操作 | ない。バッチ、ジョブ、サービス間通信 | ある。顧客が画面で操作している |
| 権限の主体 | アプリケーション、パートナーシステム、バックエンドサービス | サインイン中のユーザー |
| 監査したい対象 | 呼び出し元アプリ、パートナー、処理種別 | 個人ユーザーの操作履歴 |
| 代表例 | 在庫同期、請求連携、注文データ連携、夜間バッチ | マイページ閲覧、プロフィール変更、本人のデータ取得 |
| OAuthフロー | Client credentials | Authorization Code Flow、On-Behalf-Of Flowなど |
特に注意したいのは、「ユーザーが見られる範囲だけAPIで返したい」処理です。この場合はClient credentialsではなく、ユーザーコンテキストを保持できるフローを選ぶべきです。逆に、サービス自身が全体データを処理する業務ジョブであれば、Client credentialsのほうが設計が明確になります。
実装の基本手順
Microsoft Entra External IDの外部テナントでは、OAuth 2.0 / OpenID Connectの各フローが整理されており、外部テナントのアプリではMSALのAuthorityに<tenant-name>.ciamlogin.com形式を使うことが案内されています。また、外部テナントではClient credentialsがv2.0アプリケーションとしてサポートされています。(Microsoft Learn)
実装は、次の順序で進めると失敗しにくくなります。
| 手順 | 作業 | 設計上の確認点 |
|---|---|---|
| 1 | 保護するAPIを決める | APIのApplication ID URI、対象エンドポイント、認可単位を整理する |
| 2 | API側のアプリ登録でアプリロールを定義する | Orders.Readなど、コードで検証しやすい値にする |
| 3 | 呼び出し元のクライアントアプリを登録する | パートナー・用途・環境ごとに分ける |
| 4 | クライアントアプリへAPI permissionsを追加する | DelegatedではなくApplication permissionsを選ぶ |
| 5 | 管理者同意を付与する | 誰が、どの権限を、どのパートナーに許可したか記録する |
| 6 | トークンエンドポイントへClient credentialsで要求する | scopeは対象リソースの/.defaultを使う |
| 7 | API側でトークンと権限を検証する | aud、発行元、呼び出し元アプリ、rolesを確認する |
| 8 | 運用設計を入れる | 資格情報ローテーション、監査ログ、失効、レート制御を決める |
トークン要求では、grant_type=client_credentialsを使います。Microsoftのドキュメントでは、scopeには対象リソースの識別子に/.defaultを付けた値を渡す必要があり、複数リソースのスコープを混在させるとエラーになると説明されています。(Microsoft Learn)
HTTPで直接試す場合は、利用している外部テナントのOpenID Connectメタデータからtoken_endpointを確認し、次のような形で要求します。
curl -X POST "$TOKEN_ENDPOINT" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=<client-application-id>" \
-d "client_secret=<client-secret>" \
-d "scope=api://<api-application-id>/.default" \
-d "grant_type=client_credentials"
本番実装では、可能な限りMSALなどのサポートライブラリを使うほうが安全です。Microsoftも、直接プロトコルを実装するより、可能な場合はMicrosoft Authentication Librariesを使ってトークンを取得し、保護されたWeb APIを呼び出すことを推奨しています。(Microsoft Learn)
API側で必ず検証すべきポイント
Client credentials対応で最も危険なのは、「トークンがあるから通す」という実装です。Bearerトークンは、誰に対して発行されたのか、どのAPI向けなのか、どの権限が付与されているのかをAPI側で検証して初めて意味があります。
Microsoftのクレーム検証ドキュメントでは、認可ロジックを安全にするため、適切なAudience、データが保存されているテナントID、Subject、呼び出し元クライアントアプリの認可を確認する必要があると説明されています。アクセストークンは、そのトークンを取得した対象Web API側で検証すべきで、クライアント側で検証するものではありません。(Microsoft Learn)
最低限チェックしたいクレーム
| チェック対象 | 見るべき内容 | 失敗すると起きること |
|---|---|---|
| 署名 | Microsoft Entraの公開鍵で検証できるか | 改ざんトークンや偽トークンを受け入れる |
aud | 自分のAPI向けのトークンか | 別API向けトークンの流用を許す |
iss / テナント情報 | 期待するExternal IDテナントから発行されたか | 想定外テナントのトークンを受け入れる |
| 呼び出し元アプリ | 期待するクライアントアプリか | 未承認のパートナーやアプリから呼ばれる |
roles | 必要なアプリロールを持つか | 読み取り専用アプリが更新APIを呼べる |
アクセストークンのrolesクレームは、アプリケーションまたはユーザーに付与された権限の一覧を表します。Client credentials flowでは、ユーザースコープの代わりにこの権限セットを使ってアプリケーショントークンの認可判断を行います。(Microsoft Learn)
よくある設計ミスと回避策
ロールなしトークンを想定せずAPIを公開する
Client credentialsでは、設計によってはrolesクレームのないアプリ専用トークンが発行される可能性があります。Microsoftのドキュメントでは、ACLベースの承認パターンを有効にするため、ロールなしのアプリ専用アクセストークンが発行され得るため、API側でアクセス許可チェックを実装する必要があると説明されています。ロールなしトークンを受け入れたくない場合は、アプリへの割り当て要求を有効にする設計も検討します。(Microsoft Learn)
回避策はシンプルです。API側でrolesが空なら拒否する、または明示的に許可したappid/クライアントIDだけをACLで通す、といったルールを最初から実装してください。
1つのクライアントシークレットを複数パートナーで共有する
これは監査とインシデント対応を難しくします。1社で漏えいした場合でも全社分の資格情報を止める必要があり、どのパートナーが呼び出したのかログから判別できません。
パートナーごと、用途ごと、環境ごとにクライアントアプリを分けるのが基本です。さらに、本番では共有シークレットより証明書、または実行基盤に応じてフェデレーション資格情報を検討します。Microsoftは、より高い保証レベルのために共有シークレットの代わりに証明書やフェデレーション資格情報を使えること、資格情報をソースコードやWebページ、配布型ネイティブアプリに埋め込まないことを案内しています。(Microsoft Learn)
/.defaultの意味を誤解する
Client credentialsでは、動的に「このリクエストだけOrders.Readをください」と要求するのではなく、事前に管理者同意済みのApplication permissionsを対象リソース単位でトークンに反映します。そのため、scopeには対象APIの/.defaultを使います。
API権限の追加、管理者同意、アプリロール割り当てがそろっていないと、期待したrolesがトークンに入りません。トラブルシュートでは、まずクライアントアプリのAPI permissionsと管理者同意の状態、次にトークン内のaudとrolesを確認してください。
リフレッシュトークン前提で設計する
Client credentials flowでは、通常のユーザーサインインのようなリフレッシュトークン運用を前提にしません。Microsoftのドキュメントでは、このフローではリフレッシュトークンは付与されず、トークンが期限切れになったら/tokenエンドポイントへ再要求すると説明されています。(Microsoft Learn)
実装では、アクセストークンを短時間キャッシュし、期限切れ前に再取得する設計にします。API呼び出しのたびに毎回トークンを取り直すと、不要な認証リクエストが増え、レート制限やコスト面の問題を招きます。
B2C・パートナー向けAPIの設計例
実務で扱いやすいのは、APIを「ユーザー向けAPI」と「M2M向けAPI」に分ける設計です。
Customer App
└─ Authorization Code Flow
└─ Customer API: /me/orders, /me/profile
Partner System
└─ Client Credentials Flow
└─ Partner API: /partner/orders, /partner/inventory
Internal Job
└─ Client Credentials Flow
└─ Operations API: /jobs/reconcile, /billing/sync
同じ注文データを扱う場合でも、顧客本人が見る/me/ordersと、パートナーシステムが送信する/partner/ordersは認可の意味が違います。前者はユーザーの本人性とデータ所有範囲が重要で、後者は呼び出し元アプリと付与済みアプリロールが重要です。
アプリロール設計の具体例
| API | ロール | 説明 | 割り当て対象 |
|---|---|---|---|
| Orders API | Orders.Read.AllowedPartner | パートナーに許可された注文の参照 | 物流・販売パートナー |
| Orders API | Orders.Submit | 新規注文の登録 | 代理店システム |
| Orders API | Orders.Cancel | 注文キャンセル | 契約上許可されたパートナー |
| Inventory API | Inventory.Read | 在庫照会 | 販売チャネル |
| Billing API | Billing.Reconcile | 請求照合ジョブ | 内部バッチ |
ポイントは、ロール名を技術都合だけで決めないことです。監査時に「この権限は何を許すのか」が分かる名前にします。Api.Accessのような広すぎる権限は、初期開発では便利でも本番運用で問題になります。
導入前チェックリスト
Client credentialsをMicrosoft Entra External IDで使う前に、少なくとも次の項目を確認してください。
| 確認項目 | 判断基準 |
|---|---|
| M2M Premiumアドオンの扱い | コスト、利用ポリシー、申請フローを確認済みか |
| クライアント分割 | パートナー、用途、環境ごとにアプリ登録を分けているか |
| アプリロール | API操作単位で最小権限のロールを定義しているか |
| 管理者同意 | 誰が、何に、どの権限を承認したか記録しているか |
| 資格情報 | 共有シークレットの保管・ローテーション方針があるか |
| トークン検証 | 署名、aud、iss、呼び出し元、rolesを検証しているか |
| ログ | クライアントID、パートナーID、ロール、要求IDを記録しているか |
| 失効手順 | 漏えい時に特定クライアントだけ止められるか |
| レート制御 | トークン取得とAPI呼び出しの頻度を制御しているか |
| テスト | 権限なし、ロール違い、別Audience、期限切れトークンを拒否できるか |
まず何から始めるべきか
最初にやるべきことは、既存のB2C/パートナー連携を「ユーザー操作」と「アプリ操作」に棚卸しすることです。顧客本人の文脈が必要なAPIはAuthorization Code FlowやOn-Behalf-Of Flowで扱い、ユーザー不在のバックエンド処理やパートナーシステム連携はClient credentialsの候補にします。
次に、M2Mで呼び出されるAPIを1つ選び、アプリロール、クライアントアプリ分割、トークン検証、資格情報ローテーションまでを小さく設計します。最初から全APIを移行するより、注文参照や在庫参照のような読み取り系APIでパターンを固め、その後に更新系APIへ広げるほうが安全です。
Microsoft Entra External IDのClient credentials対応は、B2Cとパートナーアプリケーションを「人のログイン中心」から「人・アプリ・パートナーを分けた認可設計」へ進めるきっかけになります。単にトークンを取得する実装ではなく、アプリロール、管理者同意、トークン検証、運用分離まで含めて設計することが、実用的で安全なM2Mサポート活用の近道です。

コメント