AI エージェントをサードパーティ API に接続する
このガイドでは、AI エージェントがユーザーの代理としてサードパーティ API(例:Google カレンダー、GitHub など)へアクセスできるようにする手順を説明します。Logto のソーシャルコネクターと Secret Vault を活用することで、アクセス トークン (Access token) を安全に保存・管理でき、ユーザーに繰り返し再認証を求めることなくエージェントが自動タスクを実行できるようになります。
このガイドで学べること:
- サードパーティトークン保存機能付きソーシャルコネクターの設定方法
- 初回サインイン時に最小限の権限 (Permission) をリクエストする方法
- 必要に応じて追加の権限 (Permission) を段階的にリクエストする方法
- 保存されたトークンを取得し、サードパーティ API へアクセスする方法
なぜ AI エージェントにサードパーティ API アクセスが必要なのか
AI エージェントは、外部サービスと連携するタスクの自動化にますます利用されています。例えば:
- 📅 カレンダー管理:AI エージェントが Google カレンダーで自動的に会議をスケジューリングしたり、イベントを追加・調整したりできます。
- 📧 メール自動化:Gmail API を使ってフォローアップメールの送信、受信トレイの整理、返信の下書き作成などが可能です。
- 💻 コード管理:GitHub の issue 作成、プルリクエストのレビュー、リポジトリ管理など。
- 📁 ファイル管理:Google ドライブや Dropbox でファイルのアップロード、整理、共有など。
これらのタスクを実行するには、AI エージェントがユーザーの許可を得たサードパーティ API へ安全にアクセスする必要があり、OAuth トークンを正しく安全に扱うことが求められます。
仕組み
フローの概要は次の通りです:
- ユーザーがタスクを依頼:ユーザーが AI エージェントにサードパーティ API アクセスが必要なタスク(例:カレンダーイベント追加)を依頼します。
- 認可 (Authorization) プロンプト:エージェントがサードパーティアクセスの必要性を検知し、ユーザーに認可 (Authorization) を促します。
- トークン保存:ユーザーが認可 (Authorization) すると、Logto がアクセス トークン (Access token) とリフレッシュ トークン (Refresh token) を Secret Vault に安全に保存します。
- タスク実行:エージェントが保存済みトークンを取得し、サードパーティ API を呼び出してタスクを完了します。
一度認可 (Authorization) されれば、ユーザーは再認可なしで複数のタスクを実行できます。Logto はトークンを安全に保存し、必要に応じて自動的にリフレッシュするため、AI エージェントとのやり取りがシームレスになります。
前提条件
始める前に、以下を用意してください:
- Logto Cloud (または自己ホスト型 Logto v1.31 以上)のテナント
- API アクセス権を持つサードパーティプロバイダーアカウント(例:Google Cloud Console)
- Logto SDK と連携済みの AI エージェントアプリケーション(ユーザーが AI エージェントにサインイン可能)
トークン保存機能付きソーシャルコネクターの設定
AI エージェントがサードパーティ API へアクセスできるようにするには、トークン保存機能を有効にしたソーシャルコネクターを設定する必要があります。これにより、ユーザーが AI エージェントとのやり取り中にサードパーティサービスを認可 (Authorization) した際、Logto がアクセス トークン (Access token) を保存・管理できるようになります。
ここでは Google を例に説明します:
- コンソール > コネクター > ソーシャルコネクター へ移動します。
- ソーシャルコネクターを追加 をクリックし、Google を選択します。
- Google コネクター設定ガイド に従い、OAuth クライアント認証情報を設定します。
- コネクター設定で:
- 永続的な API アクセスのためにトークンを保存 を有効にし、Secret Vault へトークンを保存します。
- プロンプト に
consentを含め、ユーザーに権限 (Permission) リクエスト画面を必ず表示させます。 - オフラインアクセス を有効にし、長期間 API アクセス用のリフレッシュ トークン (Refresh token) を受け取ります。
- 変更を保存します。
このコネクターをサインイン体験に追加する必要はありません。コネクターは、AI エージェントがサードパーティ API へアクセスする際のオンデマンド認可 (Authorization) 用に使用され、ユーザーのサインインには使われません。
認可 (Authorization) をリクエストしサードパーティ API へアクセスする
AI エージェントがサードパーティ API(例:Google カレンダー)へアクセスする必要がある場合、まずユーザーがすでに認可 (Authorization) しているか確認します。未認可の場合は、ユーザーに認可 (Authorization) を促してください。
進める前に、コンソール > サインイン & アカウント > アカウントセンター で Account API を有効にしてください。詳しくは Account API の有効化方法 をご覧ください。
ステップ 1: 既存の認可 (Authorization) を確認
まず、保存済みアクセス トークン (Access token) を取得し、ユーザーがすでに認可 (Authorization) しているか確認します:
async function getGoogleAccessToken(userAccessToken: string) {
const response = await fetch(
'https://[tenant-id].logto.app/my-account/identities/google/access-token',
{
headers: {
Authorization: `Bearer ${userAccessToken}`,
},
}
);
return response.json();
}
ステップ 2: 必要に応じて認可 (Authorization) をリクエスト
トークンが存在しない場合や期限切れ、またはアクセス トークン (Access token) のスコープ拡張が必要な場合は、Logto の Social Verification API を使って認可 (Authorization) フローを開始します:
async function requestGoogleAuthorization(userAccessToken: string, scopes: string) {
// CSRF 対策のためランダムな state を生成
const state = crypto.randomUUID();
sessionStorage.setItem('oauth_state', state);
// ソーシャル認証 (Authentication) を開始
const response = await fetch('https://[tenant-id].logto.app/api/verification/social', {
method: 'POST',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
connectorId: '<google_connector_id>',
state,
redirectUri: 'https://your-ai-agent.com/callback',
scope: scopes,
}),
});
const { verificationRecordId, authorizationUri } = await response.json();
// verificationRecordId を後で使うため保存
sessionStorage.setItem('verificationRecordId', verificationRecordId);
// ユーザーを Google へリダイレクトし認可 (Authorization) を促す
window.location.href = authorizationUri;
}
ステップ 3: 認可 (Authorization) コールバックの処理
ユーザーが権限 (Permission) を付与した後、Google からアプリへリダイレクトされます。認証 (Authentication) を完了し、トークンを保存します:
async function handleAuthorizationCallback(
userAccessToken: string,
callbackParams: URLSearchParams
) {
const verificationRecordId = sessionStorage.getItem('verificationRecordId');
const storedState = sessionStorage.getItem('oauth_state');
const code = callbackParams.get('code');
const state = callbackParams.get('state');
// state を検証し CSRF 攻撃を防止
if (state !== storedState) {
throw new Error('Invalid state parameter');
}
// 認可 (Authorization) を検証
await fetch('https://[tenant-id].logto.app/api/verification/social/verify', {
method: 'POST',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
verificationRecordId,
connectorData: {
code,
state,
redirectUri: 'https://your-ai-agent.com/callback',
},
}),
});
// トークンを Logto の Secret Vault に保存
await fetch('https://[tenant-id].logto.app/my-account/identities/google/access-token', {
method: 'PUT',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
verificationRecordId,
}),
});
// 後処理
sessionStorage.removeItem('verificationRecordId');
sessionStorage.removeItem('oauth_state');
}
ステップ 4: サードパーティ API を呼び出す
これで AI エージェントがトークンを取得し、API を呼び出せます:
async function addCalendarEvent(userAccessToken: string, eventDetails: EventDetails) {
// 保存済み Google アクセス トークン (Access token) を取得
const tokenData = await getGoogleAccessToken(userAccessToken);
if (!tokenData) {
// ユーザーが認可 (Authorization) していない場合、カレンダースコープで認可 (Authorization) をリクエスト
await requestGoogleAuthorization(
userAccessToken,
'https://www.googleapis.com/auth/calendar.events'
);
return; // リダイレクト後に続行
}
// Google カレンダー API を呼び出し
const response = await fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', {
method: 'POST',
headers: {
Authorization: `Bearer ${tokenData.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(eventDetails),
});
return response.json();
}
Logto はトークンのリフレッシュを自動で処理します。アクセス トークン (Access token) が期限切れでもリフレッシュ トークン (Refresh token) があれば、取得エンドポイント呼び出し時に新しいアクセス トークン (Access token) を自動取得します。
追加の権限 (Permission) をリクエストする
AI エージェントがより多くのタスクを担う場合、追加の権限 (Permission) をリクエストする必要があります。例えば、ユーザーが最初はカレンダーの読み取り専用権限 (Permission) を認可 (Authorization) し、後からイベント作成も希望する場合、書き込み権限 (Permission) が必要です。
なぜ段階的認可 (Authorization) が重要か
- より良いユーザー体験:ユーザーは必要な理由が明確な場合、権限 (Permission) を承認しやすくなります。
- 高いコンバージョン率:最初に求める権限 (Permission) を最小限にすることで摩擦が減ります。
- 信頼構築:必要な権限 (Permission) だけを求めるアプリは信頼されます。
例:読み取りから書き込み権限 (Permission) へのアップグレード
async function createCalendarEvent(userAccessToken: string, eventDetails: EventDetails) {
const tokenData = await getGoogleAccessToken(userAccessToken);
if (!tokenData) {
// まだ認可 (Authorization) されていない場合、カレンダー書き込み権限 (Permission) を直接リクエスト
await requestGoogleAuthorization(userAccessToken, 'https://www.googleapis.com/auth/calendar');
return;
}
// イベント作成を試みる
const response = await fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', {
method: 'POST',
headers: {
Authorization: `Bearer ${tokenData.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(eventDetails),
});
if (response.status === 403) {
// 権限 (Permission) 不足の場合、追加スコープをリクエスト
await requestGoogleAuthorization(
userAccessToken,
'https://www.googleapis.com/auth/calendar' // カレンダー全体アクセス
);
return;
}
return response.json();
}
追加スコープをリクエストする際、ユーザーには新たに必要な権限 (Permission) のみが同意画面 (Consent screen) に表示されます。既存の権限 (Permission) は維持されます。
トークンステータスの管理
Logto コンソールでは、各ユーザーのトークンステータスを確認できます:
- コンソール > ユーザー管理 へ移動します。
- ユーザーをクリックして詳細を表示します。
- 接続 セクションまでスクロールし、すべての連携済みソーシャルアカウントを確認します。
- 各接続のトークンステータスは以下の通りです:
- アクティブ:アクセス トークン (Access token) が有効で利用可能
- 期限切れ:アクセス トークン (Access token) が期限切れ。リフレッシュ トークン (Refresh token) があれば次回取得時に自動更新
- 非アクティブ:この接続に保存されたトークンはありません
セキュリティのベストプラクティス
AI エージェントがサードパーティ API へアクセスする際は、以下のセキュリティ対策を心がけてください:
- 最小限のスコープをリクエスト:本当に必要な権限 (Permission) のみをリクエストする
- 段階的認可 (Authorization) を活用:一度にすべてではなく、必要なタイミングで追加権限 (Permission) をリクエスト
- トークン期限切れを適切に処理:トークンが期限切れや無効化された場合にも対応できるようにする
- ユーザーのアクセス トークン (Access token) を安全に管理:Logto のユーザーアクセス トークン (Access token) はサードパーティトークン取得の鍵です。厳重に保護してください
- API アクセスの監査:AI エージェントがサードパーティ API へアクセスした際はログを残し、トラブルシューティングやコンプライアンスに備える