認証は「あなたが誰であるか」を確認し、認可は「あなたに何ができるか」を決定します。AIを活用したアプリケーションが増える中、ログイン時に一度ユーザーの身元を確認し、その後のセッション中はエージェントが任意の操作を行えるようにする設計が増えています。これは実質的に、エージェントに「白紙委任状」を渡しているようなものです。この設計は、意図しないデータ漏洩、不要なメール送信、さらには破壊的なデータベース更新を招く恐れがあり、AIアシスタントがミリ秒単位のレイテンシで複数のツールを呼び出せるようになるにつれ、そのリスクは増大しています。

なぜこの間違いが繰り返されるのか

ほとんどのAI開発者は、ログイン画面を唯一のセキュリティゲートとして扱っています。コードはパスワードやトークンを要求し、セッションを「認証済み」としてマークした後、その後のリクエストはすべて安全であると想定してしまいます。従来のウェブアプリでは、人間のユーザーによるゆっくりとしたクリックが自然なスロットリング(流量制限)として機能します。「削除」を押す前に人間は立ち止まるからです。しかし、AIエージェントは数秒の間に数十ものツール呼び出しを実行できます。プラットフォームが「ユーザーはログインしているか?」としか確認しない場合、各呼び出しは同じ無制限の権限を継承してしまいます。

根本的な原因は利便性です。チームは、コードが複数のトークンやスコープを管理しなくて済むように、アプリケーション全体に対して単一の長寿命なサービスアカウントをプロビジョニングすることがよくあります。そのアカウントは通常、すべてのプロジェクトに対して、読み取り、書き込み、削除といった広範な権限を持っています。AIアシスタントがそのセッション内で実行されると、現在のタスクに実際にそれが必要かどうかに関わらず、自動的にそれらの権利を継承してしまいます。

何がリスクとなるのか

  • データ漏洩 – ユーザーがログインした後にあらゆるファイルを読み取れるエージェントは、機密文書を誤ってレスポンスに含めてしまい、それが後に組織外へ共有されてしまう可能性があります。
  • 意図しないアクション – サポートエンジニアのAIヘルパーは、エンジニアのセッションがアクティブであるという理由だけで、たとえクエリが対応中のチケットに関係なくても、本番データベースに対して生のSQLクエリを実行してしまう可能性があります。
  • コンプライアンス – 多くのデータ保護規則では、アクセスを最小限必要な範囲に制限することを求めています。包括的な権限モデルは、これらの原則に違反し、監査や罰金の対象となる可能性があります。
  • 運用コスト – レコードを削除または変更してしまうミスが発生すると、チームは変更のロールバック、根本原因の調査、ユーザーとの信頼回復を余儀なくされ、これらすべてが時間とコストの浪費につながります。

不足しているステップ:アクションごとの認可

認可は、入り口だけでなく、システム内のあらゆる「ドア」で評価されるべきです。問いは「これは誰か?」から「この特定の、このリソースに対する、この特定のアクションは、今すぐ実行してよいか?」へと変わります。このチェックを実装するために、完全な再設計は必要ありません。単一のセッションフラグから、短寿命でスコープ化されたトークンへと移行するだけで済みます。

実践的な仕組み

  1. 定義されたスコープを持つトークンをリクエストする – AIエージェントがツールを呼び出す必要があるとき、まず必要な正確な権限(例:read:ticketexecute:sql_query)をリストしたトークンを取得します。
  2. 各呼び出しに対してトークンを検証する – ツールが実行される前に、サービスはトークンに必要なスコープが含まれているか、およびトークンが期限切れになっていないかを確認します。
  3. リソースとスコープを照合する – リクエストが特定のプロジェクトやデータベースを対象としている場合、トークンはその識別子へのアクセスを明示的に許可していなければなりません。
  4. 拒否または許可 – いずれかのチェックに失敗した場合、呼び出しは拒否され、エージェントはユーザーに提示できるエラーを受け取ります。

コードの違いは単純です。「良くない」アプローチは以下のようになります:

if session.is_authenticated():
    tool.run(params)

「良い」アプローチは、チェックを拡張したものです:

token = get_scoped_token(user, required_scope)
if token.is_valid() and token.allows(required_scope, resource_id):
    tool.run(params)
else:
    raise PermissionError

2番目のパターンは数行増えますが、すべての操作に対してシステムに正しい問いを投げさせることを強制します。

実装を容易にする標準規格

OAuth 2.0のスコープは、トークンができることを制限するための、すでに広く採用されている方法を提供しています。project:1234:writeemail:send といったスコープをエンコードした短寿命のアクセストークンを発行することで、開発者は既存のライブラリを利用して検証ステップを実行できます。

より新しい Rich Authorization Requests (RFC 9396) はこの考え方を拡張し、クライアントが静的なリストを事前に定義するのではなく、実行時にきめ細かな権限をリクエストできるようにします。この柔軟性は、AIのワークフローがユーザーの意図に基づいて、動的に機能を追加または削除する必要がある場合に非常に有用です。

反論:シンプルさとセキュリティのトレードオフ

アクションごとのチェックは、特にAIアシスタントが多くのツールを連続して呼び出す必要がある場合、レイテンシとコードの複雑さを増大させると主張するチームもあります。彼らは、単一のセッショントークンを使用すれば、呼び出しごとに新しいトークンを取得・検証するオーバーヘッドを回避できると指摘しています。しかし、そのトレードオフは、悪用されるリスクが劇的に高まることです。最新のトークン検証サービスはマイクロ秒単位で動作するように設計されており、最小権限の原則を損なうことなく、追加のネットワークラウンドトリップをバッチ処理したりキャッシュしたりすることが可能です。データの整合性とコンプライアンスが譲れない環境においては、わずかなパフォーマンスコストよりも、リスクの軽減によるメリットの方が大きくなります。

次に注目すべき点

  • AI SDKにおけるスコープ付きトークンの採用 – 主要なAIプラットフォームのツールキットのアップデートに注目してください。多くのツールキットが、OAuthベースのスコープ用のヘルパー関数を公開し始めています。
  • Policy-as-codeフレームワーク – 新たに登場しているソリューションでは、宣言的なファイルで認可ルールを定義し、実行時にそれらを自動的に適用できるようになります。
  • アクションごとの決定内容を明らかにする監査ログ – より多くのプラットフォームが各認可チェックを記録するようになるにつれ、組織はどのAIアクションが許可またはブロックされているかを可視化できるようになり、将来的なポリシー調整に役立てることができます。

まとめ

ログイン済みのセッションを「あらゆる操作を許可するもの」として扱うことは、予期せぬ事態を招く原因となります。認可の判断をログイン時ではなく、個々のツール呼び出しごとに行うように変更し、有効期限の短いスコープ付きトークンを活用することで、AIアプリケーションは自律型エージェントの利便性を維持しながら、データの保護、規制への準拠、そして重大な事故の回避を両立できます。アクションが試行されるたびに適切な確認を行うシステムを実現するために、コードが数行増えることは、決して大きな代償ではありません。