Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【日本語版】Filter What the LLM Reads: RAG Governance...

Avatar for やくも やくも
October 25, 2026

【日本語版】Filter What the LLM Reads: RAG Governance with AgentCore Gateway

AWS Community Day Hong Kong 2026(2026年10月24日)で英語で発表した資料の日本語版です。
イベントURL:https://awscommunity.hk/

英語版: https://speakerdeck.com/yakumo/filter-what-the-llm-reads-rag-governance-with-agentcore-gateway
コード: https://github.com/shinnosukeyakumo/filter-what-the-llm-reads

Avatar for やくも

やくも

October 25, 2026

More Decks by やくも

Other Decks in Technology

Transcript

  1. Filter What the LLM Reads RAG Governance with AgentCore Gateway

    Shinnosuke Yakumo AWS Community Builder (AI Engineering), AWS User Group Leader
  2. Who am I Shinnosuke Yakumo @yakumo_09 AWS Community Builder (AI

    Engineering) 2025 Japan AWS Jr. Champions JAWS-UG NIIGATA Company: CRESCO LTD. Work: R&D, FDE Digital business card my.prairie.cards/u/yakumo_0905
  3. interceptor の実装 検証済み JWT からロールを読み、対応表を引いて filter を上書きします。 role = verified_role(request)

    # 検証済みの JWT から読む clearance = ALLOWED[role] # 対応表を引く search["filter"] = { "in": {"key": "clearance", "value": clearance}, } モデルが書いた値は、ここに一切入りません。
  4. モデル:10回とも誤った値 正しいロールが入ったのは0回でした。 ツール定義 モデルが書いた user_role 引数を定義する employee 8回 / 日本語のロール名

    2回 引数を定義しない 13回とも書かない 狭い権限のロールで、普通の質問を投げた結果です。 定義内のロールを書いた回は、一度もありません。
  5. ② 漏洩を伴わない異常終了 出し分けを担っているのは interceptor だけです。 ここが失敗して素通しすれば、全文書が返ります。 失敗のさせ方 結果 例外を投げる HTTP

    500 不正な形を返す HTTP 500 タイムアウトする HTTP 500 空を返す HTTP 500 4通りとも fail-closed で、漏洩はゼロでした。
  6. ③ 上書き方式の攻撃耐性 4通りの攻撃すべてで、ロール外の文書は0件でした。 パターン interceptor 無し 有り 通常質問 / ロールプレイ

    / 間接注入 各 3/3 漏洩 各 0/3 直接的な権限昇格の指示 0/3 漏洩 0/3 4パターンを3回ずつ、interceptor の有無で比べました。 モデルは Sonnet 4.6 です。 文書を30本に増やしても、漏洩はゼロのままでした。
  7. 失敗1:分岐を書いたツールだけ 上書きが効くのは、ツール名で分岐した2つだけです。 if tool.endswith("___kb_search"): arguments["user_role"] = role # 上書きする elif

    tool.endswith("___Retrieve"): search["filter"] = {...} # 上書きする else: pass # そのまま先へ渡す Gateway にツールを足すなら、分岐も一緒に足す必要があります。
  8. どの分岐にも当たらない呼び出し Agentic 検索(___AgenticRetrieveStream)は 名前が Retrieve で終わらないため、else を通りました。 interceptor のログ ROLE

    出ている CLAIMED / INJECTED どちらも出ない 動かなかったのではなく、どの分岐にも当たらなかっただけです。
  9. 応答まで自分で書いたモデル <tool_call> {"name": "Retrieve", ...} </tool_call> <tool_response> No results found.

    </tool_response> 申し訳ありませんが、情報が見つかりませんでした。 ツールは呼ばれていません。そして判定ログに DENY は出ません。 ツールがそもそも提示されていないからです。
  10. 失敗3:例外を握りつぶす 普通のアプリなら正しい書き方が、ここでは穴になります。 try: ...filter を注入... except Exception as e: print(f"WARN:

    {e}") # ログは出す return _passthrough(body) # そのまま先へ進む 握りつぶすと、200 で4件返り、うち2件はロール外です。
  11. 例外を外へ出す1行の修正 直し方は1行です。 握りつぶさず、Gateway まで届けます。 except Exception as e: print(f"WARN: {e}")

    raise # ← この1行 4通りに壊して、どれも HTTP 500・文書0件 で止まりました。 Gateway は代わりに止めてくれます。 ただし、例外が Gateway まで届いたときだけです。