[Auth0] Auth0 forGenAIで作る、安全なAIチャットアプリケーション

[Auth0] Auth0 forGenAIで作る、安全なAIチャットアプリケーション

Clock Icon2025.04.18

こんにちは。

ゲームソリューション部/業務効率化ソリューション部の西川です。

今回はAuth0の新機能「forGenAI」についてご紹介します。Auth0は認証・認可のプラットフォームとして広く知られていますが、最近ではAI時代に対応した新しいソリューションの提供を始めました。

https://auth0.com/ai

https://auth0.com/blog/jp-introducing-auth-for-genai-launching-identity-for-ai-agents/

はじめに

Auth0は、認証・認可のプラットフォームとして広く知られていますが、最近ではAI時代に対応した新しいソリューション「forGenAI」を提供し始めています。
この機能は、生成AIアプリケーションにおける認証・認可の課題に対応するものです。

生成AIアプリケーションでは、次のような認証・認可の課題があります。

  1. 本人確認(ログイン)をしっかり行う
    AIを使う前に、「この人は本当に本人か?」を確認する必要があります。
    たとえば、Googleアカウントや会社のアカウントでログインできるようにしたり、必要に応じて追加の確認(2段階認証など)も必要になります。

  2. AIが他のサービスと安全につながるようにする
    AIがGmailやSlackなど、他のアプリと連携する時に、**「許可された範囲だけ」**アクセスできるようにする必要があります。
    たとえば、AIがユーザーのメールを読むとき、「この人が許可したメールだけ見る」ように制限する必要があります。

  3. あとから許可を出す仕組み(非同期認可)
    AIが「この作業をしてもいいですか?」と聞いてきたとき、すぐに返事できなくても大丈夫な仕組みが必要です。
    あとから「OK」と許可すれば、AIがその作業を進められるようにする必要があります。

  4. きめ細かいアクセス制御(Fine-Grained Authorization)
    AIが扱う情報の中で、「この人にはここまで見せていい」「これは見せちゃダメ」といった細かいルールを設定できる必要があります。
    たとえば、社員Aは売上データを見られるけど、社員Bは自分の担当分だけ、というような制御が必要になります。

Auth0 forGenAIは、これらの課題に対して次のような機能を提供します。

  1. 柔軟な認証基盤

    • 様々なログイン方法(Google、GitHub、企業アカウントなど)を簡単に追加できます
    • 2段階認証やパスワードレス認証など、高度な認証機能も利用可能です
    • 既存のAuth0認証基盤があれば、それをそのまま活用できます
  2. 安全なサービス連携

    • OAuth2.0やOIDCに準拠した安全な連携機能を提供します
    • スコープベースのアクセス制御により、必要最小限の権限だけを付与できます
    • APIキーなどの機密情報を安全に管理できます
  3. 非同期認可の仕組み(Client-Initiated Backchannel Authentication)

    • Auth0のCIBAフローを使って、ユーザーの承認を非同期で取得できます
    • ユーザーはモバイルアプリのプッシュ通知で承認操作ができます
    • AIエージェントは承認を待ちながら、他の処理を続行できます
  4. Fine-Grained Authorization(FGA)

    • Auth0の新しい認可エンジンFGAを使って、非常に細かい粒度でアクセス制御ができます
    • リレーション(関係)ベースの直感的な権限モデルで、複雑なアクセス制御を簡単に実装できます
    • 大規模なシステムでも高速に動作し、リアルタイムで権限チェックができます

この記事では、実際にAuth0 forGenAIを使用してAIアプリケーションを構築する手順を紹介します。

やってみた

準備

今回は、AWS Bedrockを使用したチャットアプリケーションを作成し、Auth0 forGenAIを使って認証・認可を実装していきます。次の環境を使用します。

  • フロントエンド
    • Next.js 14(App Router)
    • Tailwind CSS
    • Auth0 SDK for Next.js(v3.5.0)
  • バックエンド
    • Next.js API Routes
    • AWS SDK for JavaScript
    • Auth0 Management API

まずは、新しいNext.jsプロジェクトを作成します。

npx create-next-app@latest auth0-genai-demo

次に、必要なパッケージをインストールします:

npm install @auth0/nextjs-auth0@3.5.0

実装

それでは、実際の実装に入っていきましょう。

まず、Auth0のダッシュボードでアプリケーションを作成します。「Applications」→「Create Application」から、次のように設定します。

続いて、APIの設定も行います。「APIs」→「Create API」から、次のように設定します。

また、RBACの設定を有効化しておきます。
スクリーンショット 2025-04-17 15.36.51

APIには2つのスコープを設定します。

  • read:messages:チャットメッセージの読み取り権限
  • write:messages:チャットメッセージの書き込み権限

ロールを作成します。
admin:read:messageswrite:messages両方
read:read:messagesのみ
スクリーンショット 2025-04-17 15.34.33

それぞれの権限を持つユーザーを作成する。
viewer@example.com:権限なし
writer@example.com:adminロール
reader@example.com:readロール
スクリーンショット 2025-04-17 15.35.58

これらの設定が完了したら、アプリケーションとAPIの情報を使って.env.localファイルを作成します。

# .env.local
AUTH0_SECRET='your-auth0-secret'  # 適当な長い文字列を設定
AUTH0_BASE_URL='http://localhost:3000'
AUTH0_ISSUER_BASE_URL='https://your-tenant.jp.auth0.com'
AUTH0_CLIENT_ID='your-client-id'
AUTH0_CLIENT_SECRET='your-client-secret'
AUTH0_AUDIENCE='https://auth0-genai-chat-api'

次は、Next.jsアプリケーションにAuth0の認証機能を組み込んでいきます。
詳細は省略させていただきます。
まず、Auth0のプロバイダーコンポーネントを作成します。

// app/providers.tsx
'use client';

import { UserProvider } from '@auth0/nextjs-auth0/client';
import { ReactNode } from 'react';

export function Providers({ children }: { children: ReactNode }) {
  return <UserProvider>{children}</UserProvider>;
}

このプロバイダーをルートレイアウトに設定します。

// app/layout.tsx
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import { Providers } from './providers';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: 'Auth0 GenAI Chat',
  description: 'Auth0 forGenAIのデモチャットアプリケーション',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ja">
      <body className={inter.className}>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

続いて、Auth0の認証APIルートを作成します。

// app/api/auth/[auth0]/route.ts
import { handleAuth } from '@auth0/nextjs-auth0';

export const GET = handleAuth();

これで、次のエンドポイントが使えるようになります。

  • /api/auth/loginでログインページにリダイレクト
  • /api/auth/logoutでログアウト処理
  • /api/auth/callbackでAuth0からのコールバックを処理
  • /api/auth/meでユーザー情報を取得

最後に、チャットのUIコンポーネントを実装します。ここではパーミッションに基づいたアクセス制御も組み込みます。

export function Chat() {
    const { user } = useUser();
    const [permissions, setPermissions] = useState<string[]>([]);
    const [messages, setMessages] = useState<Message[]>([]);
    const [input, setInput] = useState('');
    const [isProcessing, setIsProcessing] = useState(false);

    useEffect(() => {
        const fetchPermissions = async () => {
            if (!user) return;

            try {
                const response = await fetch('/api/auth/token');
                const data = await response.json();

                if (!response.ok) throw new Error(data.error);

                console.log('Token data:', data);
                setPermissions(data.permissions || []);
            } catch (error) {
                console.error('Error fetching permissions:', error);
                setPermissions([]);
            }
        };

        fetchPermissions();
    }, [user]);

    const hasPermission = (permission: string) => {
        return permissions.includes(permission);
    };

    return (
        <div className="max-w-4xl mx-auto p-4">
            <div className="mb-4 space-y-2">
                {hasPermission('read:messages') ? (
                    messages.map((msg, i) => (
                        <div key={i} className={`p-3 rounded-lg ${
                            msg.role === 'user' ? 'bg-blue-100' : 'bg-gray-100'
                        }`}>
                            {msg.content}
                        </div>
                    ))
                ) : (
                    <div className="text-red-500">
                        You don't have permission to read messages
                    </div>
                )}
            </div>

            <form onSubmit={handleSubmit} className="flex gap-2">
                <input
                    type="text"
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    disabled={!hasPermission('write:messages')}
                    placeholder={
                        hasPermission('write:messages')
                            ? "Type your message..."
                            : "You don't have permission to send messages"
                    }
                    className="flex-1 p-2 border rounded"
                />
                <button
                    type="submit"
                    disabled={!hasPermission('write:messages') || isProcessing}
                    className="px-4 py-2 bg-blue-500 text-white rounded disabled:bg-gray-300"
                >
                    Send
                </button>
            </form>
        </div>
    );
}

このチャットコンポーネントでは、ユーザーがログインすると自動的にパーミッション情報を取得します。
取得したパーミッションに基づいて、メッセージの読み取りや送信の可否を制御します。権限がない場合は、その旨をユーザーに分かりやすく表示します。

動作確認

ログインの確認

未ログイン状態では、ログインボタンが表示される。
スクリーンショット 2025-04-17 16.06.25

ログインをすることで、チャット欄が表示される。
スクリーンショット 2025-04-17 16.06.41

スクリーンショット 2025-04-17 16.06.49

権限の確認

それぞれの権限に即して、出来ることできないことが制限されていることが確認できる。

viewer@example.com:権限なし
スクリーンショット 2025-04-17 16.06.02

writer@example.com:adminロール
スクリーンショット 2025-04-17 16.05.38

reader@example.com:readロール
スクリーンショット 2025-04-17 16.05.16

さいごに

今回、Auth0 forGenAIを使ってチャットアプリケーションを作ってみましたが、実装してみると色々と発見がありました。

特に印象的だったのは、Auth0の認証基盤の柔軟さです。AIアプリケーション特有の要件に合わせて設定を変更したい場合でも、直感的なダッシュボードのおかげで簡単にカスタマイズできました。
パーミッションの設定も分かりやすく、ユーザーごとに「ここまでは見せていい」「この操作は許可する」といった具合に、きめ細かく権限を設定できます。

ただ、今回の実装では使い切れなかった機能もたくさんあります。
例えば、ユーザーの承認を非同期で取得できるCIBAフローや、より細かい権限管理ができるFGAなど。

AIアプリケーションの開発では、認証・認可の実装に頭を悩ませることも多いと思います。
「このユーザーにどこまでの権限を与えるべきか」「セキュリティを保ちながら、どうやって使いやすさを確保するか」といった課題は、どのプロジェクトでも避けて通れません。

そんな悩みを抱えている方は、ぜひAuth0 forGenAIの採用を検討してみてはいかがでしょうか。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.