AI

Cloudflareの個人AIエージェント制御入門——公開FAQと非公開APIの境界を作る

Cloudflareが11月4日に発表した個人AIエージェントの可視化・アクセス制御を解説します。設定の継承に注意しながら、Next.js・Firestore・TypeScriptで公開FAQと非公開の見積APIを分け、認証と所有者確認を保つ手順を紹介します。

2026年11月6日
CloudflareAIエージェントNext.jsFirestoreTypeScript
Cloudflareの個人AIエージェント制御入門——公開FAQと非公開APIの境界を作る

はじめに

AIによる料金比較を受け入れながら、非公開の見積書は守りたい。AIエージェントが訪れるサイトには、入口の制御と業務データの認可が必要です。

Cloudflareは2026年11月4日、個人の依頼で情報を取得・閲覧するPersonal Agentsに対して、個別のアクセス方針を設定できる更新を発表しました。設定名も AI Crawler and Agent access policies に変わっています。公式Changelog

架空の見積管理サービス「QuoteNest」を題材に、公開FAQをエージェントへ開き、Firestoreの見積は本人だけに返すAPIを作ります。入口の設定とアプリの認可を検証できるようになります。情報は2026年11月6日時点です。

何が変わったのか

Security AnalyticsのBot Analysisに Personal Assistants が加わり、Top statisticsでエージェント別の要求数、アクセス先パス、ステータスコードを調べられます。公式発表

アカウントとの関連付けは、早期アクセス中のAccount Abuse Protectionを使うサイト向けです。通常の分析だけで本人確認まで完了するわけではありません。

11月5日の記事でも、背後の利用者や委任内容を扱う課題が整理されています。以下はそれを踏まえた本記事独自の実装例です。Agents aren’t humans

ハンズオン1:Cloudflareのアクセス方針を決める

Cloudflare経由の検証用ドメインを用意し、Security → SettingsのBot trafficからAI Crawler and Agent access policiesを開きます。

区分対象となる振る舞いQuoteNestでの検討内容
Search検索用の収集・索引化公開FAQの発見を促すか
Agent利用者の依頼に応じた取得・操作比較や問い合わせ補助を受け入れるか
Training学習・追加学習用の収集学習用途の取得を認めるか

Agent向けの選択肢はAllow (do not block)、Block on pages with ads、Blockです。検証対象をAllowにして保存します。広告ページの遮断はログイン制御を代替しません。

Personal Agentsは親のAgentsポリシーを継承し、親の変更で各設定も更新されます。親を決めてから個別設定を確認してください。パス別の閲覧権限はアプリ側に実装します。公式設定ガイド

アプリのパス公開範囲
/faq、/pricing一般公開
/api/quotes/QN-001認証済みの所有者のみ
見積の確定処理別の更新処理で認可と最終確認

ハンズオン2:Firestoreの見積を本人だけに返す

Next.js App Router、Firebase Authentication、Firestoreを構成済みの検証用アプリを使います。Node.js 22以上を用意し、Firebase Admin SDKを追加してください。

yarn add firebase-admin

サーバーのApplication Default Credentialsは公式ガイドに従って設定し、鍵をブラウザへ渡さないでください。

Firestoreに検証用のquotes/QN-001を作り、ownerUidをテストユーザーのUID、summaryを「保守プランの見積」とします。以下はアプリ独自のAPIです。Firebase IDトークンを検証し、所有者が一致した場合だけ要約を返します。

// src/app/api/quotes/[id]/route.ts
import { applicationDefault, getApp, getApps, initializeApp } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";
import { getFirestore } from "firebase-admin/firestore";

export const runtime = "nodejs";

const app = getApps().length ? getApp() : initializeApp({
  credential: applicationDefault(),
});

function reply(body: object, status: number) {
  return Response.json(body, {
    status,
    headers: { "Cache-Control": "private, no-store" },
  });
}

export async function GET(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  const token = request.headers.get("authorization")?.match(/^Bearer (.+)$/)?.[1];
  if (!token) return reply({ error: "Unauthorized" }, 401);

  let uid: string;
  try {
    uid = (await getAuth(app).verifyIdToken(token)).uid;
  } catch {
    return reply({ error: "Unauthorized" }, 401);
  }

  const { id } = await params;
  if (!/^[A-Za-z0-9_-]{1,80}$/.test(id)) {
    return reply({ error: "Invalid ID" }, 400);
  }

  try {
    const doc = await getFirestore(app).collection("quotes").doc(id).get();
    const ownerUid: unknown = doc.get("ownerUid");
    if (!doc.exists || ownerUid !== uid) {
      return reply({ error: "Not found" }, 404);
    }
    const summary: unknown = doc.get("summary");
    if (typeof summary !== "string") return reply({ error: "Invalid data" }, 500);
    return reply({ id, summary }, 200);
  } catch {
    return reply({ error: "Service unavailable" }, 503);
  }
}

Route Handlerの動的パラメータはPromiseとして受け取ります。Next.js公式リファレンス

検証済みUIDと所有者を比較し、User-Agentやエージェント名で認可を省略しません。他人の見積と存在しない見積は404にそろえ、返却項目も限定します。FirebaseのIDトークン検証、Firestoreのデータ取得

Admin SDKはFirestore Security Rulesをバイパスするため、API自身で所有者を確認します。ブラウザからの直接アクセスには別途Rulesが必要です。Firebase Security Rulesの注意点

この例は委任プロトコルを実装していません。エージェント接続時には認証基盤で権限と有効期限を扱い、IDトークンをプロンプトへ貼り付けないでください。

ハンズオン3:入口とアプリを分けて検証する

まずローカルで認証なしの応答を確認します。

curl -i http://localhost:3000/api/quotes/QN-001

期待値は401です。次に検証用クライアントからIDトークンをAuthorizationのBearer値として送り、以下を確認します。トークンはログに残しません。

条件期待する結果
所有者の有効なトークン200、IDと要約のみ
別ユーザーの有効なトークン404
不正または期限切れのトークン401
認証なしでUser-Agentだけ変更401

入口はCloudflare経由の検証環境で、対応する実際のエージェントを使って確認します。Security AnalyticsでFAQへの到達を調べ、非公開APIは未認証の要求を拒否することを確かめます。

24画面へ展開する順番

QuoteNestに24画面あるなら、GitHub Issuesで「公開8画面」「本人限定12画面」「確定操作4画面」に分けます。最初にQN-101で公開範囲を合意し、QN-102で認可APIを整備します。画面への適用はその後、4画面ずつ進めます。

各Issueにはパス、公開範囲、未認証・別ユーザーでの期待値を書きます。GitHub Actionsでは既存のAPIテストとyarn buildを必須にし、親ポリシーを変更するIssueには個別設定の再確認も含めます。

まとめ

まず公開FAQでAIエージェントの到達状況を確認し、非公開APIでは認証と所有者確認を通してください。入口のアクセス方針と業務データの認可を検証してから、対応範囲を広げていきます。

サムネイル:Charles Etoroma / Unsplash(Unsplash License)。