
アーキテクチャ
イベント
マガジン
技術ブログ
2026年8月12日に、「Merpay Tech Talk 〜3年で50ヵ国へ。メルカリ決済基盤アーキテクチャ刷新の舞台裏〜」をオンラインで開催しました。 この記事はイベントレポートです。配信当日の内容を簡単に紹介します。詳しくは、YouTubeで公開している配信アーカイブ動画をご視聴ください。 イベント概要 メルカリは、日本に出品された商品を海外のお客さまが購入できる「メルカリグローバルアプリ」を提供しています。2025年に台湾でサービスを開始し、2026年春には米国でも展開しました。今後は 3年以内に50ヵ国以上へ拡大することを目指しています 。 サービスを多くの国へ展開するには、多通貨への対応だけでなく、国ごとに異なる決済手段や決済事業者との接続、言語や商習慣に合わせた決済画面、会計システムとの連携など、幅広い課題を解決する必要があります。 今回のイベントでは、グローバル展開を決済面から支えるPaymentチームのエンジニアが登壇し、決済画面と決済基盤のアーキテクチャをどのように刷新したのか、開発を通じて得られた成果や新たな課題とともに紹介しました。 登壇者 今回の登壇者は、Paymentチームでバックエンド開発に携わる以下の3名です。 tanaka0325 / 株式会社メルペイ Backend Engineer ryuyama / 株式会社メルペイ Backend Engineer tomo / 株式会社メルペイ Backend Engineer 3年で50ヵ国へ向けたPaymentチームの取り組み メルカリグローバルアプリの拡大に向けてPaymentチームのミッションには、多通貨や各国の決済手段への対応、決済画面のカスタマイズ、決済事業者との接続、会計システムとの連携などがあります。 今回のセッションでは、そのなかでも「決済画面」と「決済基盤」という2つの領域に焦点を当てました。新しい国や決済手段への展開を速めながら、プロダクトごとの柔軟性と、決済プラットフォームとしての一貫性・安全性をどのように両立したのかを説明しました。 決済画面を共通化するCheckout Solution 決済画面では、Paymentチームが提供する共通基盤「Checkout Solution」を活用しています。Checkout Solutionは、メルカリのさまざまなサービスが同じ仕組みの上で決済画面を提供できるようにするもので、2024年から国内向けに稼働しています。グローバルアプリでも、この仕組みを土台にしました。 以前は、新しいサービスを立ち上げるたびに各プロダクトチームが決済画面をゼロから実装していました。特に、3Dセキュアのような複雑な非同期フローをプロダクトごとに実装する必要があり、開発コストが大きくなるという課題がありました。 Checkout Solutionの考え方は、決済画面を「どのサービスでも同じ部分」と「サービスごとに違う部分」に分けることです。例えば、支払い方法を選ぶ欄や、購入ボタンを押したあとに支払いを確定する処理は、どのサービスでもほぼ同じです。一方で、配送方法の選択やクーポンの適用は、商品を発送するサービスと配送が不要なサービスとでは大きく異なります。 Checkout Solutionでは、前者を「Core Elements」、後者を「Flex Elements」と呼び、開発する担当も分けています。Core ElementsはPaymentチームが一度つくりすべてのサービスで共通利用し、複雑な決済処理をここに集約しています。Flex Elementsは各プロダクトチームが、自分たちのサービスに必要な要素だけを実装します。 この分け方により、新しいサービスの決済画面をつくるときは、プロダクトチームはFlex Elementsのデザインと設定を追加するだけで済み、内部の決済処理に手を入れる必要がありません。逆に、新しい決済手段を追加するときは、PaymentチームがCore Elementsを一度更新すれば、すべてのサービスの決済画面に反映されます。 グローバル展開に向けた決済基盤の刷新 決済基盤では、外部の決済事業者との接続と、残高・売上・会計イベントの管理方法を見直しました。 1つ目は、外部の決済事業者とのつなぎ方です。クレジットカード会社や各国の決済サービスなど、実際にお金を動かす事業者はPayment Service Provider(PSP)と呼ばれ、決済手段や国ごとに接続の仕方が異なります。 従来の決済サービスは日本国内向けに発展してきたため、こうしたPSPごとの接続ロジックが決済の中核サービスである Payment Service に直接組み込まれていました。その結果、新しい決済手段や通貨を1つ追加するだけでPayment Serviceに手を入れる必要があり、展開する国が増えるほど開発が難しくなる構造になっていました。 そこで、PSPとのやり取りだけを担当する「Payment Provider Service」に切り出しました。PSPごとの違いはすべてこのサービスのなかで吸収し、Payment Serviceは「どのPSPを使っているか」を意識せずに、注文から支払い完了までの流れを管理することに集中できるようにしています。 この分離によって、新しい国や決済手段を追加するときの変更範囲を、Payment Provider Serviceのなかに限定できるようになりました。 2つ目は、残高・売上・会計記録の管理方法です。決済が1件成立すると、お客さまの残高の増減、事業としての売上、そして会計上の記録という3種類の記録が発生します。従来はこれらを別々のサービスが管理し、その整合性を決済サービスが調整していたため、仕組みが複雑になり、記録どうしのずれを防ぐことが難しくなっていました。 新しい「Balance V2 + Bookkeeper」では、会計で使われる複式簿記の考え方を取り入れています。「今いくら残っているか」という残高と、「なぜ残高が変わったのか」という理由を必ずセットにし、1つのトランザクションとして同時に記録します。片方だけが記録される状態を許さないことで、決済と会計のずれを構造的に防いでいます。 刷新後の決済基盤は、グローバルアプリ向けにリリースし、クレジットカード、Apple Pay、Google Payをサポートしています。Apple PayとGoogle Payを追加した際は、上で紹介した仕組みにより、バックエンドの開発から品質保証までを約1カ月で完了できました。 最後に 3年で50ヵ国という目標に向けて、Paymentチームは決済画面と決済基盤の両面から、グローバル展開を支えるプラットフォームづくりを続けています。 今回紹介した内容の詳細や、登壇者による質疑応答は、ぜひ 配信アーカイブ動画 でご覧ください。 また、Merpay Tech Talkは、定期的にエンジニア向けのイベントを開催しています。イベント開催案内を受け取りたい方は、connpassグループのメンバーになってくださいね! メルカリconnpassグループページ 関連記事 Checkout Solutionの詳細(決済画面基盤の設計) Building a Flexible Checkout Solution: Frontend Architecture for Multi-Service Integration メルカリのグローバル展開を支えるPayment Platformの進化 グローバル展開にむけたアプリと基盤の再構築 関連求人 Merpayでは、グローバル展開を支える決済画面・決済基盤の開発に一緒に取り組む仲間を募集しています。採用情報について、詳しくは以下のエントリーをご覧ください。 Software Engineer, Backend – Merpay Product Engineer, Backend – Merpay Senior Software Engineer, Backend – Merpay Senior Product Engineer, Backend – Merpay
2026 年 9 月 25 日、 Amazon CloudWatch は CloudWatch Omni を発表しました。これは、アプリケーション中心で AI を活用し、オープンスタンダードに基づいて構築され、オフコンソールで提供される、アプリケーションと AI ワークロードの統合オブザーバビリティエクスペリエンスです。CloudWatch Omni は、AI エージェント向けに特化して構築されたオブザーバビリティ、評価、実験のためのソリューションです。評価主導のワークフロー、既存のツールのサポート、そして作業環境に直接提供されるオブザーバビリティにより、チームは、モデルプロバイダー、フレームワーク、ランタイムを問わず、AI エージェントの設計、評価、運用を行えます。オブザーバビリティは IDE に直接提供されるほか、AWS Management Console とは独立したスタンドアロンの Web エクスペリエンスからも利用できます。 エージェント型 AI システムを導入する組織は、従来のモニタリングでは対処できないオブザーバビリティの課題に直面しています。エージェントの動作は非決定的です。標準的なメトリクスでエラーが示されていなくても、プロンプトを変更すると応答品質が低下する可能性があります。チームは複数のシステムにまたがるログを手作業で確認するために何時間も費やしており、何が変更されたのか、なぜ変更されたのかを特定できないことがあります。既存のツールでは、チームはサイロ化された生成 AI モニタリングを利用するか、コーディング環境とブラウザーベースのダッシュボードを頻繁に行き来する必要がある分断されたソリューションを利用するかの選択を迫られます。 CloudWatch Omni はすべてのトレースをキャプチャし、正確性、一貫性、検索品質、ツール選択などを評価する組み込みの評価機能を備えています。Playground でプロンプトバージョンを並べて比較したり、本番トラフィックからテストデータセットを構築したり、さまざまな構成で実験を実行したり、リグレッションを自動的に検出したりできます。 開発用と運用用の2つのサーフェス CloudWatch Omni は、相互に補完する 2 つのインターフェイスを通じてオブザーバビリティを提供しま開発者は、現在サポートされている IDE である VS Code と Kiro にネイティブ拡張機能を導入できます。エージェントの実行中にトレースが表示され、プレイグラウンドや評価機能にもワンクリックでアクセスできます。運用担当者は、AWS Management Console とは独立したスタンドアロンの Web エクスペリエンスを利用してフリートをモニタリングできます。SSO 経由でアクセスでき、AWS Management Console は必要ありません。どちらも同じデータを共有します。開発者がデバッグするトレースと、運用担当者が調査するトレースは同じものです。 Cloud Login 機能 は、ローカルの IDE 環境を AWS アカウントに接続し、テレメトリデータを Amazon CloudWatch に送信して永続的に保存したり、チームとトレースを共有したり、本番環境のダッシュボードにアクセスしたりできるようにします。この接続はオプションです。開発中は CloudWatch Omni を完全にローカル環境で使用し、本番環境のエージェントをモニタリングする準備ができたら、クラウドに接続できます。 使用の開始 CloudWatch Omni を使い始める方法は 2 つあります。IDE 拡張機能(VS Code と Kiro 向け)を使用する方法と、クラウドエクスペリエンスから直接開始する方法です。クラウドエクスペリエンスでは、IDE 拡張機能をインストールせずに CloudWatch へのテレメトリデータの送信を開始できます。このチュートリアルでは、拡張機能をインストールし、エージェントを作成して実行した後、IDE からトレースと評価ツールを確認します。 VS Code Marketplace から CloudWatch Omni 拡張機能をインストールすると、アクティビティ バーに CloudWatch Omni のアイコンが表示されます。ウェルカム画面から、[ サンプルプロジェクトを開始する ] を選択して、事前設定されたエージェントにサンプルトレースデータをロードするか、Command+Shift+P(macOS の場合)または Ctrl+Shift+P(Windows/Linuxの場合)を使用してコマンドパレットへのショートカットを使用し、[オムニ:新しいプロジェクトの作成] を選択します。 図 1.CloudWatch オムニウェルカムスクリーンと VS Code での新規プロジェクトの作成 サンプルプロジェクトには、エージェントの実装とサンプルデータセットが含まれています。使用開始時の設定の一環として、OpenTelemetry の計測機能を追加します。CloudWatch Omni が各手順をガイドします。新しいエージェントを最初から作成することもできます。CloudWatch Omni では、インタラクティブなチャットを使ってプロセスを進めます。チャットでエージェントの目的を定義し、モデルプロバイダーを選択して、ツールを設定します。デフォルトでは、すべてのデータはローカルに保存されます。必要に応じて AWS に接続し、Amazon CloudWatch にデータを送信できます。 設定を確認した後、ローカル開発サーバーを起動し、エージェントに質問を送信しました。これが一般的なチャットボットインターフェースと異なるのは、次に何が起こるかということです。「 トレースを表示 」を選択すると、エージェントがリクエストをどのように処理したかが正確に表示されます。 図 2.CloudWatch Omni は、AI コードアシスタントをガイドし、テスト用のローカル開発環境を設定できるようにします CloudWatch Omni は、Kiro、Claude Code、Codex などの AI コードアシスタントと統合し、セットアッププロセスを効率化します。これらのアシスタントは、Dev Server の設定、依存関係のインストール、計測機能の設定を代わりに行うことができるため、手動で設定することなく、インストールから最初のトレース付きエージェントセッションの実行までを数分で完了できます。 図 3.エージェントとのやり取りとトレースの表示 トレースは AI エージェントの動作を理解するために不可欠です。従来のリクエストとレスポンスのシステムとは異なり、エージェントは 1 回の呼び出しで複数の意思決定を行います。ツールの選択、プロンプトの組み立て、サブコールの連鎖などが含まれます。トレース全体を可視化できなければ、エージェントが誤った回答を生成した理由や、予期しない処理経路をたどった理由の診断は推測に頼ることになります。CloudWatch Omni は、すべてのステップを構造化されたタイムラインに記録するため、動作が想定から外れた箇所を正確に特定できます。 Trace Explorer では、エージェントが実行したすべてのステップ(LLM 呼び出し、ツールの呼び出し、推論ステップ)を、構造化された階層型タイムラインで詳細に確認できます。任意のスパンを詳細に確認して、入力、出力、トークン使用量、レイテンシーを調査できます。 図 4。エージェントの実行タイムラインを表示するトレースエクスプローラー Trace Explorer は比較モードもサポートしています。比較モードでは 、2 つのトレースを並べて表示し、異なるプロンプトや設定が動作にどのように影響するかを確認します。比較モードは、リグレッションのデバッグに特に役立ちます。また、 Ask Assistant を使用すると 、AI エージェントがトレースから表面のパターンや異常を分析し、「なぜエージェントはこのツールを2回呼び出したのか」などの質問に答えます。 図 5。2 つのトレースを並べて比較する 評価は、生成 AI のオブザーバビリティを、実際の品質改善につながるものに変える役割を果たします。レイテンシーやエラー率などの従来のメトリクスでは、エージェントの応答が有用で、一貫性があり、事実に基づいて正確なものかどうかを判断できません。評価機能は、各応答を品質の観点から評価することで、ユーザーが実際に体験する品質を測定し、標準的なモニタリングではまったく検出できないリグレッションを発見できるようにします。 CloudWatch Omni には、一貫性、有用性、忠実性、ルーティングの正確性などのメトリクスに対応する 17 種類の組み込み評価機能が含まれています。Trace Explorer からトレースを選択し、評価機能を選んで評価を実行しました。カスタム評価フレームワークを構築することなく、各サンプルのスコアと集計メトリクスを取得できました 。 図 6.トレースの評価の実行 そこから、 Playground を使用してさまざまなシステムプロンプトを並べてテストし、複数のモデルとプロンプト構成をリアルタイムで比較して、変更を加える前に各バリエーションが出力品質にどのように影響するかを確認しました。Experiments ビューを使用すると、同じデータセットに対して 2 つのエージェントのバリエーションを実行し、評価スコア、レイテンシー、トークン使用量を並べて比較できるため、パフォーマンスの高い構成を選択できます。 図 7 。Omni Experimentsコンソールでのエージェントバリアントの評価比較 Prompt Management を使用すると 、プロンプト構成を長期にわたってバージョン管理および追跡できるため、新しいバージョンのパフォーマンスが低下した場合でも、簡単にロールバックできます。 CloudWatch Omni には、完全な会話履歴を確認し、エージェントが複数ターンのインタラクションをどのように処理するかを把握できる Session Explorer も用意されています。また、 Agent Topology ビューでは、サブエージェント、ツール、およびそれらの相互接続を含むエージェントシステムのアーキテクチャを可視化できます。任意のノードを詳細に確認して、パフォーマンスを調査し、ボトルネックを特定できます。 CloudWatch Omni には、IDE を使用せず、任意のブラウザーからアクセスできる専用の Web エクスペリエンスも用意されています。チームは、アプリケーションモニタリング、分析、エージェントのオブザーバビリティ、AI を活用した調査など、すべての機能に共同でアクセスできます。 図 8.アプリケーションモニタリング、分析、エージェントオブザーバビリティを備えた CloudWatch Omni ウェブエクスペリエンス トレースをキュレーションしてゴールデンデータセットにし 、構造化された実験を行いました。 Experiment 関数は 、データセットに対してエージェントを実行し、結果を自動的に評価します。プロンプトやエージェントのロジックが変更されるたびに、リグレッションテスト用のベンチマークを作成できます。 サポートされているフレームワークで構築されたエージェントがすでにある場合、CloudWatch Omniはインストルメンテーションを追加するための2つの方法を提供します。 1つはフレームワークを検出してトレースを自動的に設定する Auto-Instrumentswith Kiro 、 もう1つは Python と TypeScript 用のすぐに使えるコードスニペットを使った手動インストゥルメンテーションです 。詳細なインストルメンテーションガイドについては、 CloudWatch Omni ドキュメントを参照してください。 サポートされているフレームワークとオープンスタンダード 上記のチュートリアルではサンプルプロジェクトを使用していますが、CloudWatch Omni は、チームがすでに使用しているエージェントフレームワークにも対応しています。LangChain、LangGraph、CrewAI、OpenAI SDK、Strands、Vercel AI SDK など、Python と TypeScript の両。また、 Amazon Bedrock AgentCore で構築されたエージェントにネイティブなオブザーバビリティを提供し、AgentCore の評価機能を使用してエージェントの品質をオムニワークフロー内で直接評価します。 計測機能には、エージェントが Lambda、ECS、EKS、その他のクラウドのいずれで実行されている場合でも、オープンスタンダード(OpenInference および ADOT)が使用 。評価については、Omni は Braintrust、DeepEval、Ragas などのサードパーティー評価ツールと統合できるほか、組み込みのデータセット、プレイグラウンド、バッチ実験も利 。再プラットフォーム化は不要です。 CloudWatch Omni は、エージェントのオブザーバビリティとアプリケーションのオブザーバビリティを 1 つのエクスペリエンスに統合します。アプリケーションのオブザーバビリティ体験については、関連記事「 Amazon CloudWatch Omni の紹介:人工知能を活用したアプリケーションのコラボレーティブオブザーバビリティ 」を参照してください。 料金と利用可能なリージョン Amazon CloudWatch Omni が一般公開されました。IDE 拡張機能は自由に使用できます。開始するのに AWS アカウントは必要ありません。Amazon Bedrock のモデルを使用する場合は AWS 認証情報のみが必要で、OpenAI や Anthropic などの他のプロバイダーを使用する場合は API キーのみが必要です。 VS Code マーケットプレイスから拡張機能をインストールして 、今すぐ始めましょう。 すべての機能を調べてすぐに使い始めるには、 CloudWatch on AWS Builder Center にアクセスしてください。 API を呼び出したり、ドキュメントを検索したり、リージョンごとの提供状況を確認したり、この新機能に関するトラブルシューティングを確認したりする場合は、お好みの AI ツールで AWS MCP Server と プラグイン を使用してみてください。 AWS re:Post でフィードバックを共有するか、通常の AWS サポート の連絡先からお問い合わせください。 ハッピービルディング! – Daniel Abib 原文は こちら です。
財務アナリストが AI アシスタントに「私の担当する顧客請求書のうち、支払期日を過ぎているものはどれですか?」と尋ね、SAP から直接その答えが返ってくる、そんな場面を想像してみてください。企業はまさにこれを求めていますが、AI エージェントを記録システムに接続する際には難しい問いが生じます。エージェントが SAP にアクセスするとき、そのリクエストを行っているのは誰なのか、という問いです。初期の統合の多くは、すべてのリクエストを 1 つの共有 SAP サービスユーザー経由でルーティングします。これでは、すべてのユーザーの操作が単一のテクニカルユーザーにマッピングされてしまうため、SAP は実際の操作者を認可・監査できなくなり、さらにセキュリティおよびコンプライアンスチームがめったに承認しない静的な SAP 認証情報の保存を強いられます。その結果、有望な AI パイロットが本番稼働に至る前に停滞してしまいます。 完全な ID 伝播は、SAP に至るすべての認証区間を通じて各ユーザーの ID を引き継ぐことでこの問題を解決します。リクエストが指名されたユーザーとして到着すると、SAP はそのユーザー自身の権限を適用し、Security Audit Log にそのユーザーの操作として記録し、共有された恒久的な認証情報を一切保存しません。 RFC 8693 のトークン交換で定義されている On-Behalf-Of(OBO)アクセスは、ユーザーの既存トークンを SAP にスコープを絞ったダウンストリームトークンと交換することで、これを可能にします。Microsoft Entra ID や Okta などのエンタープライズ ID プロバイダー(IdP)はこのフローをサポートしているため、ユーザーは 2 度目のログインプロンプトなしで SSO を利用できます。本ブログでは、その体験を構築する方法を解説します。 Amazon Quick を使って SAP の販売オーダー、財務、プラント保全について質問し、さらにアクションを実行しながら、 AWS for SAP MCP Server と Microsoft Entra ID などのエンタープライズ IdP によって、あなたの ID を SAP まで引き継ぎます。 仕組み エンドツーエンドのフローには 4 つの構成要素があります。MCP クライアントとして動作する AI エージェント(Amazon Quick)、AWS for SAP MCP Server をホストする Amazon Bedrock AgentCore Runtime、Entra ID、そして SAP システムです。フローを通過するために、Amazon Bedrock AgentCore 内には 2 つの異なる認証境界が設定されます。 インバウンド : Amazon Quick が、そのユーザーが誰であるかを AgentCore に証明します。AgentCore は Entra ID に対してユーザー ID を検証します。 アウトバウンド : AgentCore が SAP に受け入れられるトークンを取得します。OBO 交換により、SAP リソースにスコープを絞ったこのトークンが生成されます。 図 1. Amazon Quick、AWS for SAP MCP Server、SAP S/4HANA を統合したシングルサインオンのための高レベルアーキテクチャ。 ユーザーは Entra ID ログイン(メールアドレス)またはシングルサインオンを通じて Amazon Quick にサインインします Amazon Quick は OAuth 2.0 を介して Entra ID でこのユーザーを認証し、AWS for SAP MCP Server にアクセスします AgentCore は Entra ID でアクセストークンを検証します AgentCore はすべてのユーザーアクセスを AgentCore Observability に記録します AWS for SAP MCP Server は Entra ID と OBO 交換を実行し、その JSON Web Token(JWT)が SAP への HTTPS API 呼び出しで使用されます Entra ID が提供する JWT は、SAP の OpenID Connect(OIDC)Trust によって検証されます この設計では、以下に説明する 3 つの Entra ID アプリ登録を使用します。 Amazon Quick Client App – Quick がユーザーをサインインさせるために使用する OAuth クライアント。 Inbound / Resource App – インバウンドトークンを検証し、OBO 交換を実行します。AgentCore の認証情報プロバイダーはその client_id を使用し、これは Quick のトークンの aud でもあります。 Outbound App – SAP アクセススコープを表します。SAP は最終トークンをこのアプリに対して検証します。 Microsoft Entra ID ベースのプロバイダー設定と、関連する構成要素について理解するには、 AgentCore Identity のドキュメント を参照してください。 図 2. 3 つの Entra ID アプリ登録にまたがる委任権限のチェーン。 SAP BTP Integration Suite も、OBO(On Behalf Of)トークンチェーンを通じてこのパターンをサポートし、ID フローを次のように拡張します。Amazon Quick → AWS for SAP MCP Server → SAP BTP Integration Suite → SAP S/4HANA。SAP BTP でプリンシパル伝播と呼ばれる ID 伝播は、SAP BTP API Management によって処理されます。SAP ソリューションへの MCP アクセスパターンに関するベストプラクティスについては、SAP の ガイダンス を参照してください。 実装の詳細 本セクションでは、Entra ID アプリ登録から SAP ユーザーマッピングまで、エンドツーエンドの設定を構成する手順を説明します。この設定の前提条件は以下のとおりです。 要件 詳細 Azure CLI Global Administrator または Application Administrator ロールで認証済みの az CLI AWS CLI 対象の AWS アカウントとリージョン向けに構成済み SAP BASIS 7.56 SP1 以降(または SAP Note 3313726 を適用した 7.52) SAP トランザクション SOIDC が利用可能であること CloudFormation テンプレート s3://awsforsap-mcp-server-setup-{region}/cfn-launch-template/latest/ の最新版 Amazon Quick MCP コネクターを作成するアクセス権。コネクターを登録すると Entra ID に Amazon Quick クライアントアプリが作成されます。Step 4 で使用するため、Entra ID ポータル(App registrations)からその QUICK_APP_ID、QUICK_OBJECT_ID、および委任スコープ ID を取得してください。 OIDC サポートの最新情報については、 SAP のドキュメント を参照してください。 Step 1: インバウンド Entra ID アプリ登録を作成する インバウンドアプリは、MCP クライアントが AgentCore Runtime に認証するために使用するトークンを発行します。この手順の 2 つの設定が、フローの後半で重要になります。まず、 requestedAccessTokenVersion を 2 に設定します。これは OBO 交換と SAP 検証のいずれもが v2.0 トークンを期待するためです。次に、 access_as_user 委任スコープを公開します。これは、Quick クライアントアプリがユーザーの代わりにこのアプリを呼び出すために要求する権限です。 TENANT_ID="<your-entra-tenant-id>" INBOUND_APP_NAME="agentcore-mcp-inbound" # Create the inbound app registration az ad app create --display-name "$INBOUND_APP_NAME" --sign-in-audience "AzureADMyOrg" # Capture the Application (client) ID and Object ID INBOUND_APP_ID=$(az ad app list --display-name "$INBOUND_APP_NAME" --query "[0].appId" -o tsv) INBOUND_OBJECT_ID=$(az ad app list --display-name "$INBOUND_APP_NAME" --query "[0].id" -o tsv) # Require v2.0 tokens and set the Application ID URI az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${INBOUND_OBJECT_ID}" \ --body '{"api":{"requestedAccessTokenVersion":2}}' az ad app update --id "$INBOUND_APP_ID" --identifier-uris "api://${INBOUND_APP_ID}" # Expose the access_as_user delegated scope INBOUND_SCOPE_ID=$(uuidgen) az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${INBOUND_OBJECT_ID}" \ --body "{\"api\":{\"requestedAccessTokenVersion\":2,\"oauth2PermissionScopes\":[{\"adminConsentDescription\":\"Access AgentCore MCP Server\",\"adminConsentDisplayName\":\"access_as_user\",\"id\":\"${INBOUND_SCOPE_ID}\",\"isEnabled\":true,\"type\":\"User\",\"userConsentDescription\":\"Access AgentCore MCP Server on your behalf\",\"userConsentDisplayName\":\"Access AgentCore MCP\",\"value\":\"access_as_user\"}]}}" # Create the service principal az ad sp create --id "$INBOUND_APP_ID" Step 2: アウトバウンド Entra ID アプリ登録を作成する アウトバウンドアプリは SAP アクセスを表します。AgentCore Identity はこれを OBO 交換のターゲットとして使用し、SAP は最終トークンをこれに対して検証します。この手順では sap_access スコープを公開し、インバウンドアプリが要求できる対象を用意します。また、インバウンドアプリを既知のクライアントアプリケーションとして事前承認します。これは、ユーザーに同意を求めることなく、Entra ID が 2 つのアプリ間で OBO トークンを発行できるようにする設定です。 OUTBOUND_APP_NAME="agentcore-mcp-obo-sap" az ad app create --display-name "$OUTBOUND_APP_NAME" --sign-in-audience "AzureADMyOrg" OUTBOUND_APP_ID=$(az ad app list --display-name "$OUTBOUND_APP_NAME" --query "[0].appId" -o tsv) OUTBOUND_OBJECT_ID=$(az ad app list --display-name "$OUTBOUND_APP_NAME" --query "[0].id" -o tsv) # v2.0 tokens + Application ID URI az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${OUTBOUND_OBJECT_ID}" \ --body '{"api":{"requestedAccessTokenVersion":2}}' az ad app update --id "$OUTBOUND_APP_ID" --identifier-uris "api://${OUTBOUND_APP_ID}" # Expose the sap_access delegated scope (SAP validates tokens against this) OUTBOUND_SCOPE_ID=$(uuidgen) az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${OUTBOUND_OBJECT_ID}" \ --body "{\"api\":{\"requestedAccessTokenVersion\":2,\"oauth2PermissionScopes\":[{\"adminConsentDescription\":\"Access SAP on behalf of user\",\"adminConsentDisplayName\":\"sap_access\",\"id\":\"${OUTBOUND_SCOPE_ID}\",\"isEnabled\":true,\"type\":\"User\",\"userConsentDescription\":\"Access SAP on your behalf\",\"userConsentDisplayName\":\"SAP Access\",\"value\":\"sap_access\"}]}}" az ad sp create --id "$OUTBOUND_APP_ID" # Pre-authorize the inbound app as a known client application (enables OBO) az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${OUTBOUND_OBJECT_ID}" \ --body "{\"api\":{\"knownClientApplications\":[\"${INBOUND_APP_ID}\"]}}" Step 3: 権限と管理者同意を構成する この手順では、インバウンドアプリにアウトバウンドアプリの sap_access スコープへの委任権限を付与し、それを管理者同意します。この付与が OBO チェーンのインバウンドからアウトバウンドへの部分を有効にします。なぜなら、Entra ID は要求元アプリがターゲットスコープへの同意済み委任権限を保持している場合にのみ OBO トークンを発行するためです。 az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${INBOUND_OBJECT_ID}" \ --body "{\"requiredResourceAccess\":[{\"resourceAppId\":\"${OUTBOUND_APP_ID}\",\"resourceAccess\":[{\"id\":\"${OUTBOUND_SCOPE_ID}\",\"type\":\"Scope\"}]}]}" az ad app permission admin-consent --id "$INBOUND_APP_ID" Step 4: OBO 権限チェーンを構成する この手順は権限チェーンを完成させるもので、不完全な場合 OBO 交換は失敗します。Entra ID は OBO トークンを発行する前に、次の 4 つを一括で検証します。 アサーションの aud が交換を行う client_id と一致すること クライアントアプリがターゲットスコープへの委任権限を保持していること ターゲットアプリの knownClientApplications にクライアントチェーン全体が含まれていること サービスプリンシパルに対する oauth2PermissionGrant が存在すること 重要な設計原則: OBO クライアントはトークンのオーディエンスと一致しなければならない。 Entra ID OBO では、トークン交換を実行する client_id がアサーショントークンの aud クレームと一致する必要があります。Amazon Quick のトークンは aud = Inbound App ID を持つため、AgentCore の認証情報プロバイダーはアウトバウンドアプリではなくインバウンドアプリの認証情報を使用しなければなりません。ここでの不一致は最も一般的な失敗原因であり、 AADSTS500131 (アサーションオーディエンスの不一致)または AADSTS7000114 (OBO が許可されていない)として現れます。 以下のコマンドは、これらの各要件を構成します。Amazon Quick クライアントアプリを作成済み(前提条件を参照)で、その QUICK_APP_ID、QUICK_OBJECT_ID、およびスコープ ID を取得済みであることを前提とします。 # 1. Add Quick + Inbound to the OUTBOUND app's knownClientApplications az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${OUTBOUND_OBJECT_ID}" \ --body "{\"api\":{\"knownClientApplications\":[\"${INBOUND_APP_ID}\",\"${QUICK_APP_ID}\"]}}" # 2. Add Quick to the INBOUND app's knownClientApplications az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${INBOUND_OBJECT_ID}" \ --body "{\"api\":{\"knownClientApplications\":[\"${QUICK_APP_ID}\"]}}" # 3. Grant the Quick client delegated access to both scopes, then admin-consent az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${QUICK_OBJECT_ID}" \ --body "{\"requiredResourceAccess\":[{\"resourceAppId\":\"${INBOUND_APP_ID}\",\"resourceAccess\":[{\"id\":\"${INBOUND_SCOPE_ID}\",\"type\":\"Scope\"}]},{\"resourceAppId\":\"${OUTBOUND_APP_ID}\",\"resourceAccess\":[{\"id\":\"${OUTBOUND_SCOPE_ID}\",\"type\":\"Scope\"}]}]}" az ad app permission admin-consent --id "$QUICK_APP_ID" # 4. Create the oauth2PermissionGrant for the INBOUND service principal INBOUND_SP_ID=$(az ad sp show --id "$INBOUND_APP_ID" --query "id" -o tsv) OUTBOUND_SP_ID=$(az ad sp show --id "$OUTBOUND_APP_ID" --query "id" -o tsv) az rest --method POST \ --uri "https://graph.microsoft.com/v1.0/oauth2PermissionGrants" \ --body "{\"clientId\":\"${INBOUND_SP_ID}\",\"consentType\":\"AllPrincipals\",\"resourceId\":\"${OUTBOUND_SP_ID}\",\"scope\":\"sap_access\"}" # 5. Emit the email claim on the OUTBOUND app — this is the only claim SAP uses for user mapping az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${OUTBOUND_OBJECT_ID}" \ --body '{"optionalClaims":{"accessToken":[{"name":"email","essential":true}]}}' Step 5: インバウンド Entra ID アプリの詳細を AWS Secrets Manager に保存する AgentCore Identity は認証情報プロバイダーを通じて OBO 交換を実行します。この手順における以下の選択は必須であり、Entra ID が OBO リクエストを検証する方法から直接導かれます。 アウトバウンドアプリではなく、インバウンドアプリの認証情報を使用してください。 Entra ID OBO では、交換を行う client_id がアサーショントークンの aud と一致する必要があり、Quick のトークンは aud = Inbound App ID を持ちます。 AWS_REGION="us-east-1" # Client secret for the INBOUND app + store it in AWS Secrets Manager INBOUND_APP_SECRET=[REDACTED_PASSWORD] ad app credential reset --id "$INBOUND_APP_ID" \ --display-name "obo-exchange-secret" --query "password" -o tsv) aws secretsmanager create-secret \ --name "AWSforSAP-MCP-OAuthCredentials-EntraId" \ --secret-string "{\"clientId\":\"${INBOUND_APP_ID}\",\"clientSecret\":\"${INBOUND_APP_SECRET}\"}" \ --region "$AWS_REGION" Step 6: AWS CloudFormation で MCP Server をデプロイする この手順では、AWS CloudFormation を使って AWS for SAP MCP Server をデプロイします。2 つのパラメーターがサーバーによるリクエスト認証の方法を決定し、CloudFormation は両方の認証コンポーネントをプロビジョニングするため、いずれも手作業で構築する必要はありません。InboundAuthProvider を Entra ID に設定すると、インバウンド認証のために AgentCore Runtime に JWT オーソライザーがアタッチされます。これはランタイム組み込みの JWT オーソライザーであり、Entra ID のディスカバリー URL と許可されたオーディエンスから構成されるもので、別個のカスタムオーソライザーではありません。AuthFlow を ON_BEHALF_OF_TOKEN_EXCHANGE に設定すると、アウトバウンドの OBO 交換を実行する MicrosoftOauth2 認証情報プロバイダーが作成されます。次の表のパラメーターは、サーバーを Entra ID テナントと 2 つのアプリ登録に接続します。 パラメーター 値 SapBaseUrl https://<sap-host>/sap/opu/odata/sap/ SapSystemType S4HANA または ECC InboundAuthProvider Entra ID DiscoveryUrl https://login.microsoftonline.com/{TENANT_ID}/v2.0/.well-known/openid-configuration AllowedAudiences {INBOUND_APP_ID} AuthFlow ON_BEHALF_OF_TOKEN_EXCHANGE SapCredentialsSecret AWSforSAP-MCP-OAuthCredentials-EntraId SapTokenUrl https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token OauthScopes api://{OUTBOUND_APP_ID}/sap_access McpServerReadEnabled true McpServerWriteEnabled true McpServerCreateEnabled true McpServerUpdateEnabled true McpServerDeleteEnabled true McpServerFunctionImportEnabled true TEMPLATE_URL="https://awsforsap-mcp-server-setup-${AWS_REGION}.s3.${AWS_REGION}.amazonaws.com/cfn-launch-template/latest/AwsForSapMcpServerStack.template.json" aws cloudformation create-stack \ --stack-name "sapmcp-${UNIQUE_ID}" \ --template-url "$TEMPLATE_URL" \ --parameters \ ParameterKey=UniqueId,ParameterValue="${UNIQUE_ID}" \ ParameterKey=SapBaseUrl,ParameterValue="${SAP_BASE_URL}" \ ParameterKey=SapSystemType,ParameterValue="S4HANA" \ ParameterKey=InboundAuthProvider,ParameterValue="EntraId" \ ParameterKey=DiscoveryUrl,ParameterValue="https://login.microsoftonline.com/${TENANT_ID}/v2.0/.well-known/openid-configuration" \ ParameterKey=AllowedAudiences,ParameterValue="${INBOUND_APP_ID}" \ ParameterKey=AuthFlow,ParameterValue="ON_BEHALF_OF_TOKEN_EXCHANGE" \ ParameterKey=SapCredentialsSecret,ParameterValue="AWSforSAP-MCP-OAuthCredentials-EntraId" \ ParameterKey=SapTokenUrl,ParameterValue="https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token" \ ParameterKey=OauthScopes,ParameterValue="api://${OUTBOUND_APP_ID}/sap_access" \ ParameterKey=McpServerVpcSecurityGroup,ParameterValue="${VPC_SG}" \ ParameterKey=McpServerNetworkSubnets,ParameterValue="${SUBNET_ID}" \ ParameterKey=McpServerReadEnabled,ParameterValue="true" \ ParameterKey=McpServerWriteEnabled,ParameterValue="true" \ ParameterKey=McpServerCreateEnabled,ParameterValue="true" \ ParameterKey=McpServerUpdateEnabled,ParameterValue="true" \ ParameterKey=McpServerDeleteEnabled,ParameterValue="true" \ ParameterKey=McpServerFunctionImportEnabled,ParameterValue="true" \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \ --region "$AWS_REGION" aws cloudformation wait stack-create-complete --stack-name "sapmcp-${UNIQUE_ID}" --region "$AWS_REGION" # Verify both auth components were created aws bedrock-agentcore-control get-oauth2-credential-provider \ --name "AWSForSAP-MCP-OAuth2-Provider-${UNIQUE_ID}" --region "$AWS_REGION" \ --query "{vendor:credentialProviderVendor, clientId:oauth2ProviderConfigOutput.microsoftOauth2ProviderConfig.clientId, status:status}" # Register the CFN-created credential provider's callback URL on the inbound app CALLBACK_URL=$(aws bedrock-agentcore-control get-oauth2-credential-provider \ --name "AWSForSAP-MCP-OAuth2-Provider-${UNIQUE_ID}" --region "$AWS_REGION" \ --query "callbackUrl" --output text) az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/${INBOUND_OBJECT_ID}" \ --body "{\"web\":{\"redirectUris\":[\"${CALLBACK_URL}\"]}}" デプロイ後の手順: スタックが正常に作成された後、MCP Server のエンドポイント URL を インバウンドアプリの Identifier URI として登録し(Amazon Quick はこれを resource パラメーターとして送信します)、認証情報プロバイダーのコールバック URL をインバウンドアプリのリダイレクト URI として登録します。 次の表は、各認証コンポーネントとその作成元となるパラメーターをまとめたものです。ランタイム構成の型は customJWTAuthorizer という名前ですが、これは Entra ID の発行者とオーディエンスでパラメーター化された AgentCore Runtime の標準 JWT オーソライザーであり、別個のオーソライザーを記述・デプロイする必要はありません。 コンポーネント 型 自動作成元 Inbound Auth Provider ランタイム上の customJWTAuthorizer InboundAuthProvider + DiscoveryUrl + AllowedAudiences Outbound OAuth2 Provider ランタイム上の MicrosoftOauth2 認証情報プロバイダー AuthFlow=ON_BEHALF_OF_TOKEN_EXCHANGE + SapCredentialsSecret(+ SapTokenUrl + OauthScopes) Step 7: SAP OIDC トラストとユーザーマッピングを構成する SAP 側では、トランザクション SOIDC で OIDC トラストを作成し、SAP に Entra ID からのトークンを受け入れるよう指示します。この手順で ID 伝播が実体を持ちます。なぜなら、SAP はトークンをサービスアカウントではなく指名されたユーザーにマッピングするためです。SAP は以下を検証します。 iss : トークン発行者があなたの Entra ID テナントでなければなりません。 aud : Outbound App ID と一致しなければなりません。 署名 : Entra ID が公開する JWKS に対して検証されます。 ユーザーマッピング : SAP はトークン内の email クレームを個々の SAP ユーザーにマッピングします。 図 3. Entra ID 向けの SAP OIDC 構成 マッピングは email に基づくため、各ユーザーの SAP ビジネスパートナーまたはユーザーレコードが、Entra ID が発行するのと同じメールアドレスを保持していることを確認してください。この一致が、認証済みトークンを MULLERF のような特定の SAP ユーザーに解決するものです。 Step 8: OBO フローをエンドツーエンドでテストする フローをテストする前に、AWS for SAP MCP Server を Amazon Quick のコネクターとして追加します。これは Entra ID に Amazon Quick クライアントアプリをプロビジョニングする手順でもあります。コネクターを追加するには、次の手順を実行します。 Amazon Quick でコネクター(MCP サーバー)設定を開き、新しい MCP コネクターの追加を選択します。 Step 6 の CloudFormation スタック出力にある AWS for SAP MCP Server のエンドポイント URL を入力します。 認証(Authenticate)の手順で「User authentication method」を選択し、Auth 構成を「Custom user based OAuth」に設定して、Entra ID テナントの OAuth フィールドを入力します。次を指定します — Client ID として Amazon Quick クライアントアプリの AppID(client)、Public OAuth client はチェックしないまま、Client secret、Authorization URL(https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize)、および Token URL(https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token)。 コネクターを保存し、対話型サインインを一度完了します。Amazon Quick は Entra ID にクライアントアプリケーションを登録します。その QUICK_APP_ID、QUICK_OBJECT_ID、およびスコープ ID を取得し、権限チェーンをまだ完了していない場合は Step 4 を実行します。 コネクターが配置されたら、実際のユーザーとしてサインインし、「私の未処理の販売オーダーを表示して」のような、SAP の読み取りにマッピングされる自然言語の質問をします。テストが成功すると、以下が確認されます。 Quick が SAP パスワードのプロンプトなしで Entra ID に対してあなたを認証します。 MCP Server が SAP データを返します。 SAP では、Security Audit Log(トランザクション SM20 )がリクエストをサービスアカウントではなくあなたのユーザーに帰属させます。この最後の点が、ID がエンドツーエンドで伝播したことの証明です。 トランザクション SOIDC で、OIDC トラストがトークンの email クレームを個々の SAP ユーザーにマッピングしていることを確認し、コネクターと CloudFormation の構成が SAP サービスアカウントの認証情報を一切保持していないことを検証します(保存される唯一のシークレットは AWS Secrets Manager 内の Entra ID インバウンドアプリのクライアントシークレットです)。これは、アクセスが共有 SAP パスワードではなく ID 伝播によって付与されていることを証明します。 トラブルシューティング 以下の注記は、最も一般的な問題に対処します。 AADSTS500131(アサーションオーディエンスの不一致) : 認証情報プロバイダーが誤った client_id を使用しています。Quick のトークンの aud と一致する、インバウンドアプリのものでなければなりません。 AADSTS7000114(OBO が許可されていない) : Step 4 の権限チェーンが不完全です。knownClientApplications、委任権限の付与、管理者同意、および oauth2PermissionGrant を確認してください。 SAP がトークンを拒否する : SOIDC トラストの iss、aud = Outbound App ID を再確認し、email クレームが存在し(Step 4.5)、SAP ユーザーと一致していることを確認してください。 始めましょう AI エージェントに SAP へのアクセスを与えることは、ユーザーごとのセキュリティを諦めることを意味しません。Amazon Bedrock AgentCore を基盤とする AWS for SAP MCP Server を使えば、あなたの ID をバックエンドまで完全に保持しながら、Amazon Quick を通じて SAP と対話できます。 このソリューションは 4 つの成果をもたらします。 監査証跡が個々のユーザーのアクションを記録します。 SAP は、すべての AI 主導のリクエストを、共有サービスアカウントではなく実在の人物として認証、認可、監査します。 SAP パスワードを一切保存しません。 OBO 交換は完全にサーバーサイドで実行され、保存される唯一のシークレットは Entra ID インバウンドアプリの認証情報です。 最小権限と監査を維持します。 SAP は引き続きユーザー自身のロールを適用し、そのアクションをユーザー自身の ID の下で記録します。 スコープを分離した設計。 クライアント、インバウンド、アウトバウンドの各アプリを分離し、OBO 交換ではトークンオーディエンスと一致させるためインバウンドアプリの認証情報を使用します。 始めるには、Microsoft Entra ID と AgentCore Identity の On-Behalf-Of トークン交換を用いて AWS for SAP MCP Server をデプロイしてください。これにより、共有 SAP 認証情報なしで、AI エージェントに SAP へのセキュアなユーザーごとのアクセスを提供できます。 Fortescue、PLDT、Harman などのお客様が、どのように AWS for SAP MCP Server を活用してエージェント型 AI の強化を実現しているかについては、 AWS for SAP Blog をご覧ください。今すぐ構築を始めましょう。始めるには、 AWS for SAP MCP Server のページをご覧ください。AWS が何千もの SAP のお客様にとって選ばれるプラットフォームでありイノベーションの場である理由については、 AWS for SAP のページをご覧ください。 著者について Ferry Mulyadi Ferry は、シンガポールの Amazon Web Services(AWS)における World Wide SAP Tech Alliance Principal Partner Solution Architect であり、25 年以上にわたるエンタープライズアプリケーションとクラウドの経験を活かして、エージェント型 AI の進化をリードしています。彼は、人工知能と SAP エコシステムを橋渡しする自律型ワークフロー、エージェント主導のトランスフォーメーションパターン、エンタープライズ規模の統合フレームワークを設計しました。 Rengarajan Sridharan Renga は、AWS の AI and Strategic Partner Engineering における Senior Technical Program Manager であり、SAP ワークロードに焦点を当てたプログラムを推進しています。エンタープライズリソースプランニング(ERP)ソリューションで 20 年以上の経験を持つ Renga は、お客様やパートナーがエンタープライズシステムをモダナイゼーションし、ビジネス価値を最大化してデジタルトランスフォーメーションの成果を推進できるよう支援することを専門としています。 本ブログの翻訳は Amazon Quick による自動翻訳を行い、パートナー SA 松本がレビューしました。原文は こちら です。



















