Auth0 for AI AgentsのToken Vaultが、「何トークンを保管するのか」「保管するだけなのか」検証・いろいろ考察してみた
はじめに
本記事は SaaSで加速するゲーム開発 - Advent Calendar 2025 - の 15 日目のブログです。
前回あらすじ
前回の記事では、2025年11月にGAとなった Auth0 for AI Agents の概要と、サンプルアプリケーション(Next.js + Vercel AI SDK)を使い、この機能の何が嬉しい点を検証しました。
嬉しいポイントをまとめると
「従来、AIエージェントは回答を生成するために多くのリソースにアクセスする必要があるため、AIエージェントには管理者権限を付与しがちだった。しかし、この機能を使うとAIを実行するユーザーの権限でAIを実行できるように簡単に実装できる。その結果、AIは必要以上の情報を回答しなくなる。」
こんな感じでした。
さて、本日はAuth0 for AI Agents 第2の機能である Token Vaultを紹介・検証したいと思います。
Auth0 Token Vaultとは
アプリケーションからサードパーティ・クレデンシャルのステート管理(リフレッシュトークンの保存や更新ロジック)をオフロードする機能です。
Google 等のリフレッシュトークンを Auth0 基盤内でセキュアに永続化し、アクセストークンの有効期限管理および更新処理(Refresh Grant)を代行します。これにより、開発者はトークンの有効期限を意識することなく、ステートレスな実装のまま長期間の API アクセス権限を維持できます。
従来のリフレッシュトークンの管理方法だと、サードパーティのリフレッシュトークンはアプリ開発者側で保持する方法を考え、実装する必要がありました。
テンプレ的な実装だと
- データベースにトークン管理用のテーブルを設計・作成する。
- API を叩く直前に毎回アクセストークンの有効期限をチェックする。
- 期限切れの場合は、サードパーティ(Google等)のトークンエンドポイントを叩いて更新(Refresh Grant)し、DBを更新するミドルウェアを書く。
Token Vault は、こうした煩雑な独自実装を一切不要にし、リフレッシュトークンの管理責務を Auth0 へと完全に委譲することを可能にします!
リフレッシュトークン管理の整理・考察
- Public Client
- 従来
- ブラウザに保存(in-memoryもあり得るが、どっちにせよ危険で短命)
- XSSなどで漏洩する危険性が非常に高い
- 保存しない場合、アクセストークンの有効期限が切れたタイミングで再認証となるため、ユーザー体験が悪くなる
- ブラウザに保存(in-memoryもあり得るが、どっちにせよ危険で短命)
- Token Vault
- Auth0の内部ストレージに保存
- ブラウザには短命のアクセストークンしか降りてこないため、安全
- リフレッシュ処理はAuth0側が行うため、永続的に連携先の機能を利用することが可能
- 従来
- Confidential Client
- 従来
- 自前のDBに保存
- リフレッシュ処理も自前で実装
- 永続的に連携先の機能を利用可
- Token Vault
- Auth0の内部ストレージに保存
- リフレッシュ処理はAuth0側が行うため、永続的に連携先の機能を利用することが可能
- 従来
つまり
Token Vaultを利用することでDB管理が不要となりリフレッシュトークン更新の実装が無くなる。
そしてPublic Clientの場合、リフレッシュトークン露出の機会が減るため安全性が増す。
このToken Vault。AIの文脈で紹介されてますけど、AIじゃなくても実装を省コストにする、とても有用な機能だと分かりますね( auth0-ai パッケージに実装があるのですが、これがAI文脈以外で使えるかどうか未検証 )
検証
では、本当にAuth0側でリフレッシュトークンを保管して更新をしてくれるのでしょうか。
公式チュートリアルを改変して検証してみます。
※公式チュートリアルだと、シンプルにGoogle Calerdar APIと連携してカレンダー情報を取得するシナリオとなっているので、Token Vaultが機能したかどうか分かりません。
まず、チュートリアル通り進めてAIが機能するところまで進めましょう!

Google DeveloperコンソールでOAuthクライアントの作成が無事に済んでいればカレンダーから情報を取得することが出来ます!(チュートリアル通り)
「私の今日の予定は?」

Googleの認証が動く

Auth0からGoogleへのアクセスを同意する

AIが私のカレンダーの予定を回答してくれる!

ここからが改変ポイントです。
裏側ではToken VaultにGoogleのリフレッシュトークンが保管されているのですが、それをこの挙動から確認することは出来ません。
そのため、以下のような実験を行います。
Google APIのアクセストークンの有効期限1時間経過後、改めて今日の予定をAIに聞く。
→TokenExchange(更新)が行われて、新しいアクセストークンが払い出されるはずであり、有効期限が新しくなっていることを確認する。
■アクセストークン取得処理にログを仕込む
// src/lib/auth0-ai.ts
export const getAccessToken = async () => getAccessTokenFromTokenVault();
追加した部分:
export const getAccessToken = async () => {
const credentials = await import('@auth0/ai/TokenVault')
.then(m => m.getCredentialsFromTokenVault());
if (credentials) {
const token = credentials.accessToken;
const expiresIn = credentials.expiresIn || 0;
// ↓↓↓ ここを追加 ↓↓↓
console.log('[検証ログ] AT 取得:', {
先頭: token.substring(0, 10),
末尾: token.substring(token.length - 10),
有効期限: `${expiresIn}秒 (${(expiresIn / 60).toFixed(0)}分)`
});
// ↑↑↑ ここまで追加 ↑↑↑
return token;
}
return undefined;
};
■Google APIのアクセストークンの有効期限1時間経過後、改めて今日の予定をAIに聞く
はじめて予定を聞く
[検証ログ] AT 取得: { '先頭': 'ya29.a0Aa7', '末尾': 'HnjpMw0206', '有効期限': '3598秒 (60分)' }
有効期限が切れたあとに聞く、トークンが変更された
[検証ログ] AT 取得: { '先頭': 'ya29.a0Aa7', '末尾': 'FU64FQ0207', '有効期限': '3598秒 (60分)' }
ハマりポイント
私だけかも知れないですが、Auth0アプリケーションの設定で、「リフレッシュトークンのローテーション」を有効化できるところがあります。

こちら、Token Vaultを利用する場合は有効にしないでください。
他のすべての設定が正常でも、ここの設定を間違っているとサンプルアプリが動かなくなります。
私の場合、それっぽい設定なので有効にしてしまい、原因究明まで半日ほど時間を溶かしてしまいました。。
チュートリアルにはちゃんと disable にしろって書いてるんですけどね。。思い込みはよくない。。。
Scroll down to the Refresh Token Rotation section and disable the Allow Refresh Token Rotation option.
以上です。







