{
  "format": "agent-article-v0",
  "article_id": "EA-283",
  "canonical_url": "/tools/ea-283-cache-isolation-cross-user-leakage",
  "page_type": "reference",
  "claim_ids": [],
  "evidence_ids": [
    "EVD-EA-283-URL-AC2AEFB331C7",
    "EVD-EA-283-URL-D1EDFF5FF95C",
    "EVD-EA-283-URL-69921CB77BE4",
    "EVD-EA-283-URL-FB87768384BB",
    "EA-283-CURRENT-APPROVAL",
    "EA-283-CURRENT-BODY-READBACK"
  ],
  "unknown_ids": [
    "EA-283-UNKNOWN-01"
  ],
  "operational_object_ids": [],
  "provider": [],
  "models": [],
  "plans": [],
  "surfaces": [],
  "regions": [],
  "current_status": "CURRENT",
  "observation_status": "SPEC_ONLY",
  "freshness": "CURRENT",
  "last_verified": "2026-10-20",
  "supersedes": [],
  "superseded_by": [],
  "provenance": [
    "MANUAL-EA283-DRAIN-20261020-C1",
    "SRC-EA-283-URL-AC2AEFB331C7",
    "SRC-EA-283-URL-D1EDFF5FF95C",
    "SRC-EA-283-URL-69921CB77BE4",
    "SRC-EA-283-URL-FB87768384BB",
    "BODY-SHA256:485ac3b08d74a9b5f32cf7af187dd62379c5a6f08d91b561cbd6f6bcbd22d0f1"
  ],
  "article_sources": [
    {
      "id": "EVD-EA-283-URL-AC2AEFB331C7",
      "evidence_class": "RESEARCH",
      "title": "[S1] vLLM Semantic Router Issue #2134:",
      "href": "https://github.com/vllm-project/semantic-router/issues/2134",
      "supports": [],
      "limit": "元の監査済み資料に記載された参照先です。URLの復元は、資料の最新性や全主張の支持を新たに検証したことを意味しません。",
      "origin_class": "SOURCE_PACKET_REFERENCE",
      "source_or_experiment_ids": [
        "SRC-EA-283-URL-AC2AEFB331C7"
      ],
      "supporting_locators": [
        "出典・provenance",
        "S1",
        "- [S1] vLLM Semantic Router Issue #2134: https://github.com/vllm-project/semantic-router/issues/2134"
      ],
      "scope": "出典・provenance",
      "provenance_status": "SOURCE_PACKET_REFERENCE_PROJECTED"
    },
    {
      "id": "EVD-EA-283-URL-D1EDFF5FF95C",
      "evidence_class": "RESEARCH",
      "title": "[S2] vLLM Semantic Router PR #2135:",
      "href": "https://github.com/vllm-project/semantic-router/pull/2135",
      "supports": [],
      "limit": "元の監査済み資料に記載された参照先です。URLの復元は、資料の最新性や全主張の支持を新たに検証したことを意味しません。",
      "origin_class": "SOURCE_PACKET_REFERENCE",
      "source_or_experiment_ids": [
        "SRC-EA-283-URL-D1EDFF5FF95C"
      ],
      "supporting_locators": [
        "出典・provenance",
        "S2",
        "- [S2] vLLM Semantic Router PR #2135: https://github.com/vllm-project/semantic-router/pull/2135"
      ],
      "scope": "出典・provenance",
      "provenance_status": "SOURCE_PACKET_REFERENCE_PROJECTED"
    },
    {
      "id": "EVD-EA-283-URL-69921CB77BE4",
      "evidence_class": "RESEARCH",
      "title": "[S3] Microsoft llm-semantic-cache-lookup policy:",
      "href": "https://learn.microsoft.com/en-us/azure/api-management/llm-semantic-cache-lookup-policy",
      "supports": [],
      "limit": "元の監査済み資料に記載された参照先です。URLの復元は、資料の最新性や全主張の支持を新たに検証したことを意味しません。",
      "origin_class": "SOURCE_PACKET_REFERENCE",
      "source_or_experiment_ids": [
        "SRC-EA-283-URL-69921CB77BE4"
      ],
      "supporting_locators": [
        "出典・provenance",
        "S3",
        "- [S3] Microsoft llm-semantic-cache-lookup policy: https://learn.microsoft.com/en-us/azure/api-management/llm-semantic-cache-lookup-policy"
      ],
      "scope": "出典・provenance",
      "provenance_status": "SOURCE_PACKET_REFERENCE_PROJECTED"
    },
    {
      "id": "EVD-EA-283-URL-FB87768384BB",
      "evidence_class": "RESEARCH",
      "title": "歴史的所在記録:",
      "href": "https://docs.google.com/document/d/1Vd0BP7G2UyPDRQs_-8dPvTgQ78Tk6kcVGuMJjqNdr84/edit",
      "supports": [],
      "limit": "元の監査済み資料に記載された参照先です。URLの復元は、資料の最新性や全主張の支持を新たに検証したことを意味しません。",
      "origin_class": "SOURCE_PACKET_REFERENCE",
      "source_or_experiment_ids": [
        "SRC-EA-283-URL-FB87768384BB"
      ],
      "supporting_locators": [
        "出典・provenance",
        "- 歴史的所在記録: https://docs.google.com/document/d/1Vd0BP7G2UyPDRQs_-8dPvTgQ78Tk6kcVGuMJjqNdr84/edit"
      ],
      "scope": "出典・provenance",
      "provenance_status": "SOURCE_PACKET_REFERENCE_PROJECTED"
    },
    {
      "id": "EA-283-CURRENT-APPROVAL",
      "evidence_class": "RESEARCH",
      "title": "現行本文の監査・revision対応",
      "supports": [
        "現行台帳のAUDIT_PASSと候補・revision・本文ハッシュの対応を確認しています。"
      ],
      "limit": "監査状態と来歴の記録です。外部根拠の最新性や本文の全主張を追加保証しません。",
      "origin_class": "AUDITED_CANONICAL_RESEARCH_PACKET",
      "source_or_experiment_ids": [
        "MANUAL-EA283-DRAIN-20261020-C1"
      ],
      "supporting_locators": [
        "1KqhJtiSb2S84rWmeYVwKcT_76dBwZ_B0ZZuAWQqH0rQ/EA_REVISION_LEDGER#ea_id=EA-283&revision_id=EA-283-RESEARCH-20261020-R1&candidate_id=MANUAL-EA283-DRAIN-20261020-C1",
        "EA-283-RESEARCH-20261020-R1"
      ],
      "provenance_status": "CURRENT_CANONICAL_APPROVAL_READBACK"
    },
    {
      "id": "EA-283-CURRENT-BODY-READBACK",
      "evidence_class": "IMPL",
      "title": "現行本文の収録照合",
      "supports": [
        "公開生成入力の本文SHA-256が、監査済み候補に結び付いたハッシュと一致しています。"
      ],
      "limit": "本文の同一性の検査です。外部システムの挙動や全主張の真偽を実証したものではありません。",
      "checked_at": "2026-10-21",
      "origin_class": "IMPLEMENTATION_READBACK",
      "source_or_experiment_ids": [
        "BODY-SHA256:485ac3b08d74a9b5f32cf7af187dd62379c5a6f08d91b561cbd6f6bcbd22d0f1"
      ],
      "supporting_locators": [
        "content/staging/EA-283.md",
        "485ac3b08d74a9b5f32cf7af187dd62379c5a6f08d91b561cbd6f6bcbd22d0f1",
        "EA-283-RESEARCH-20261020-R1"
      ],
      "provenance_status": "CURRENT_APPROVED_BODY_HASH_MATCH"
    }
  ],
  "research_sections": [
    {
      "heading": "要点と前提",
      "text": "AIのキャッシュ分離は、一度生成・検索した結果を再利用するとき、別の利用者や権限範囲へ内容が漏れないようにする設計である。同じ質問であっても、利用できる文書、会話履歴、テナント、利用目的が違えば、再利用してよい回答も違う。「意味が近い」「同じモデルを使う」という条件は、情報を共有してよい根拠にはならない。\n\nLLMの回答キャッシュだけでなく、検索結果、ツール結果、会話要約、アプリのメモリ、CDN、ブラウザ、実行中の同時要求をまとめる仕組みも調べる必要がある。一層だけで利用者別キーを実装しても、前後の共有層が同じ結果を返せば分離は崩れる。"
    },
    {
      "heading": "キャッシュの種類ごとに境界を決める",
      "text": "| 層 | 再利用されるもの | 分離上の確認点 |\n|---|---|---|\n| 完全一致の回答キャッシュ | 入力や設定の一致に対応した生成結果 | 入力以外の権限・データ版・履歴がキーへ反映されるか |\n| 意味的キャッシュ | 埋め込みの近さに基づく回答 | 類似検索の前または返却前に厳密な認可区画を強制するか |\n| 検索・ツールキャッシュ | 文書断片、検索結果、API応答 | 実行主体、対象資源、現在の閲覧権限を維持するか |\n| 同時要求の共有 | 実行中処理や一時的なPromise、待機先 | 別利用者が同じ進行中結果へ相乗りしないか |\n| HTTP・端末側 | HTML、JSON、ダウンロード、履歴 | 認証付き結果が共有経路や次の利用者へ残らないか |\n| 推論基盤のキャッシュ | モデル入力の前置き等 | 提供者・版の仕様と、アプリの回答キャッシュを混同しないか |\n\nキャッシュ名が同じでも、保存内容、区画、失効方法、提供者の保証は違う。入力トークンの処理を省く仕組みを、アプリが保存する回答の共有許可と同一視しない。どの層が何の内容を保持するかを一覧化する。"
    },
    {
      "heading": "正しいキーより先に、共有してよい範囲を決める",
      "text": "公開FAQのように全員へ同じ情報を返す用途は、共有キャッシュが適する場合がある。一方、顧客契約、人事、個人の作業状態に基づく回答は、利用者または認可範囲を分ける必要がある。同じテナントの中でも閲覧権限が異なるため、tenant_idだけで十分とは限らない。\n\nキーや区画の候補には、認証由来のテナント・主体、権限またはポリシーの版、参照データの版、モデル・プロンプト版、検索・ツール設定、会話の必要部分がある。ただし全情報を平文でキーに含めれば、キーやログ自体から機密情報が漏れる。秘匿識別子の設計、正規化、区切り、衝突、長さ、バージョンを管理する。ハッシュ化は表現の工夫であり、取得者への認可の代わりではない。\n\n共通グループの回答を共有する場合、そのグループが同じ名前を持つだけでなく、同じ閲覧可能範囲を持つことを確認する。権限が動的なら、ヒット時に参照文書の現在の認可を再検査するか、認可変更で区画を失効させる設計が必要になる。許可リストが取得できないとき、古い回答をそのまま返すかは業務要件に照らして明示的に決める。機密用途では検査不能時に再利用しない構成を検討する。"
    },
    {
      "heading": "意味の近さで利用者を分けない",
      "text": "意味的キャッシュでは、質問にユーザーIDを付け足して埋め込むだけでは、別ユーザーの質問が十分遠くなる保証がない。vLLM Semantic RouterのIssue #2134は、ユーザーごとの接頭辞を使う構成でも別利用者の回答が返ったとする再現報告である。[S1] 検証すべきなのは識別文字列が違うことだけでなく、実際のキャッシュ検索が別区画の候補を排除することである。\n\n対応PR #2135は2026-06-16にマージされ、インメモリバックエンドで類似度とは別の厳密なscope gateを設ける変更を示している。PRは他バックエンドへの追随と、候補の事後除外によるヒット率の限界を別に記述する。[S2] この修正が存在することから、未確認の配備版や全バックエンドの修正済みを推定しない。実使用コミット、バックエンド、設定を照合する。\n\nAzure API Managementの意味的キャッシュ資料も、類似回答が不適切・古い・安全でない場合があると注意し、`vary-by`でキャッシュを区分する仕組みを示す。[S3] ただしどの値で区分するかは実装側の責任である。本文のuserフィールドや任意ヘッダーではなく、認証と認可に結び付いた値を使い、lookupとstoreで同じ範囲を適用する。類似度閾値を厳しくすることと、アクセス範囲を強制することは別の対策である。"
    },
    {
      "heading": "典型的な漏えい経路",
      "text": "利用者Aの質問「今月の契約額は」がAの文書に基づいて回答され、その結果が質問文だけで保存されたとする。Bが同じ質問をしたとき、モデルを呼ばずAの回答が返れば、検索の認可は実行されない。対策はキャッシュを認可済みの区画へ保存し、ヒット経路にも同じ境界を適用すること。検索APIの権限テストだけでは検出できない。\n\n別の経路として、AとBの同時質問を一つの実行へまとめるsingle-flight処理がある。永続キャッシュを利用者別にしても、進行中要求のキーが質問文だけなら、BがAの実行結果を受け取る可能性がある。永続化されない共有状態も含めて区画を揃える。\n\n管理者が権限を削除した後も、TTLが残っている間は以前の回答が表示される場合がある。TTLは保持時間の上限を補助するものであり、即時失効を意味しない。データ・権限・プロンプトの変更イベントから失効対象を引ける仕組み、または版の変更で古い区画を使わない仕組みを設ける。旧データをバックアップから復元した後にも失効条件を適用する。"
    },
    {
      "heading": "読取りだけでなく書込みも保護する",
      "text": "不正な利用者が共有キャッシュへ任意の回答を保存できれば、情報漏えいに加えて、他者の回答を汚染する問題になる。登録経路の認証、区画を変更する権限、値の形式、書込み元の来歴を管理する。信頼できない保存値を、そのまま実行可能なオブジェクトへ復元する設計も避ける。\n\n可観測性では、利用者別のヒット・ミス、拒否、不一致、失効遅延、対象版を記録する。ただし問題調査のためにキャッシュの機密全文を広いログへ転記しない。保存・閲覧の監査と、回答内容そのものの保持を分ける。漏えいが疑われる場合は、該当区画または機能の再利用を停止し、影響対象を識別して失効・権限修正・再検証を行う。"
    },
    {
      "heading": "安全性とヒット率の両方を測る",
      "text": "模擬データを用意し、Aの回答を保存した後、Bから同じ質問、言い換え、長い質問を送って漏えいしないことを確認する。テナント切替、組織内の権限差、ID欠落、失効、削除、並行実行、外部キャッシュ障害、復旧後を含める。埋め込みが同一でも別区画を返さない試験は、類似度に依存しない境界の確認に有効である。\n\n厳密な区画を付けると、共有ANN索引の上位候補が他区画に偏り、正当な回答もヒットしなくなる場合がある。ヒット率を戻すために区画検査を外さず、検索対象の分割や候補探索方法を調整する。測定は、情報の越境がないことと、同じ区画で十分再利用できることを別指標にする。"
    },
    {
      "heading": "OPEN_UNKNOWN",
      "text": "- 実使用のキャッシュ層、バックエンド、キー、認証由来scope、失効方式、提供者の推論キャッシュ仕様は未取得。\n- クロスユーザー、同時要求、権限失効、削除伝播、汚染、障害復旧、実ヒット率の試験はNOT_RUN。\n- Issue／PRは当時の再現と限定された修正の証拠。対象配備の影響有無・修正版・全バックエンドの現在状態は未判定。"
    },
    {
      "heading": "SAFE_WORDING",
      "text": "「再利用を許す範囲を明示し、類似度とは独立した認可区画と失効制御を、保存・検索・同時要求の全経路で強制する」。一方、「IDをプロンプトへ混ぜれば分離済み」「類似度を上げれば漏えいしない」「TTLがあるので権限失効も即時」「修正PRがマージ済みだから全配備が安全」とはしない。"
    },
    {
      "heading": "出典・provenance",
      "text": "確認日: 2026-10-20。工程・制御・試験の組合せは本稿の設計提案。\n\n- [S1] vLLM Semantic Router Issue #2134: https://github.com/vllm-project/semantic-router/issues/2134 （ユーザーscopeの再現報告。EA-281で扱う全体分離の具体例）\n- [S2] vLLM Semantic Router PR #2135: https://github.com/vllm-project/semantic-router/pull/2135 （インメモリ修正、マージ日、バックエンドとヒット率の限界）\n- [S3] Microsoft llm-semantic-cache-lookup policy: https://learn.microsoft.com/en-us/azure/api-management/llm-semantic-cache-lookup-policy （類似検索とvary-by区分。現行の実配備設定を別途確認）\n- 歴史的所在記録: https://docs.google.com/document/d/1Vd0BP7G2UyPDRQs_-8dPvTgQ78Tk6kcVGuMJjqNdr84/edit 、tab=t.0:21984–23383、特に22423–22490。完成先行本文は確認できず、所在確認記録を保持した新候補である。"
    }
  ],
  "human_url": "/tools/ea-283-cache-isolation-cross-user-leakage",
  "markdown_url": "/agent/article.md?path=%2Ftools%2Fea-283-cache-isolation-cross-user-leakage",
  "json_url": "/agent/article.json?path=%2Ftools%2Fea-283-cache-isolation-cross-user-leakage"
}