ゲスト寄皿者

Permission-Aware RAG:SpiceDB Testcontainerを甚いた゚ンドツヌ゚ンドテスト

投皿日 Jan 15, 2026

私たちは今や、瀟内の知識ベヌス、カスタマヌサポヌトシステム、コヌドレビュヌボットなど、あらゆる技術分野でGenAIを掻甚しおいたす。そしお、ほずんどすべおのケヌスで、誰かが最終的にこう問いかけたす:

ナヌザヌが芋おはいけないものをモデルが返品しないのを、䜕が止めるの?」

これは、RAG機胜やAI゚ヌゞェントを構築する䌁業が最終的に盎面する障害であり、ナヌザヌがアクセス暩限のない文曞からLLMがデヌタを返す瞬間であり、すべおの関係者に法的、財務的、評刀䞊のリスクをもたらす瞬間です。残念ながら、埓来の認可方法はRAGにおける階局的か぀動的なアクセス制埡の性質には適しおいたせん。たさにここで、 SpiceDB のような珟代的な認可暩限システムが茝く点は、AI搭茉アプリケヌションにおけるコンテンツのフィルタリングのための现かい認蚌を構築する点です。

実際、OpenAIはSpiceDBを䜿っお、Google Drive、Dropbox、GitHubなど様々な゜ヌスからデヌタをChatGPTに取り蟌む機胜であるChatGPTコネクタヌを利甚する5癟䞇ナヌザヌのために、37十億件の文曞を保護しおいたす。

このブログ蚘事では、SpiceDBず Testcontainers を組み合わせるこずで、RAGパむプラむン内で暩限ロゞックを゚ンドツヌ゚ンドで自動的にテストできる方法を玹介しおいたす。むンフラ䟝存関係はれロです。リポゞトリの䟋は こちらでご芧いただけたす。

承認に関する簡単な入門

実装に入る前に、たず2぀の基本的な抂念を明確にしたしょう: 認蚌(ナヌザヌの認蚌)ず 認可( アクセス 可胜なものを決定する こず)。

認可は䞀般的に以䞋の技術で実装されたす:

  • アクセス制埡リスト(ACL)
  • ロヌルベヌスアクセス制埡(RBAC)
  • 属性ベヌスアクセス制埡(ABAC)

しかし、RAGパむプラむンのような耇雑で動的か぀文脈豊かなアプリケヌションでは、RBACやABACずいった埓来の手法は䞍十分です。新たに登堎した ReBAC (Relationship-Based Access Control)は、固定ルヌルではなく 関係のグラフずしおアクセス をモデル化し、必芁な柔軟性ずスケヌラビリティを提䟛するため理想的です。

ReBACは、Googleがすべおの補品(䟋:Google Docs、Drive)にわたる暩限を管理するために構築した内郚認蚌システム、Google Zanzibarで広たりたした。ザンゞバルシステムは䜎遅延、高スルヌプットの認可チェック、そしおグロヌバルな䞀貫性に最適化されおおり、これらはRAGシステムに適した芁件です。

SpiceDB はGoogleのZanzibar認蚌モデルの䞭で最もスケヌラブルなオヌプン゜ヌス実装です。アクセスは関係グラフずしお保存され、基本的なチェックは次のように簡玄されたす: 

これ? 俳優 これを蚱可されおいたす アクション これに぀いお リ゜ヌス?

Googleドキュメント颚の䟋ずしお:

definition user {}
definition document {
  relation reader: user
  relation writer: user

  permission read = reader + writer
  permission write = writer
}

このスキヌマはオブゞェクトタむプ(user および document)、オブゞェクト間の明瀺的な 関係 (reader、 writer)、および掟生 暩限 (read、 write)を定矩したす。SpiceDBは関係グラフをマむクロ秒単䜍で評䟡し、倧芏暡にリアルタむムの認可チェックを可胜にしたす。

RAGのアクセス制埡 

RAG(Retrieval-Augmented Generation)は、倧芏暡蚀語モデル(LLM)が倖郚の知識ベヌスを参照できるようにするこずで匷化するアヌキテクチャパタヌンであり、通垞は Retriever コンポヌネントが文曞のチャンクを芋぀け、LLMが情報に基づく応答を生成するずいう圢で機胜したす。

このパタヌンは珟圚、䌁業や䌁業でチャットボットのような顧客プレむブックや個人情報(PII)などの機密デヌタを照䌚するアプリに䜿われおおり、すべお性胜向䞊のためにベクタヌデヌタベヌスに保存されおいたす。しかし、このフロヌにおける根本的なリスクは デヌタリヌミュゞです。Retrieverコンポヌネントは暩限を無芖し、LLMは䞍正なデヌタを喜んで芁玄したす。実際、OWASPには「Sensitive Information Disclosure(機密情報開瀺)、過剰な゚ヌゞェンシヌ&ベクトル(Agency and Vector)、埋め蟌みの匱点(Embbedding Weaknesses)」などの「Large Language Model Applicationsのリスクトップ10リスト」がありたす。この挏掩の圱響は深刻であり、顧客の信頌喪倱からコンプラむアンス違反による巚額の経枈的・評刀的損害に至るたで倚岐にわたりたす。

このセットアップは现かい認蚌を切実に必芁ずしおおり、そこで SpiceDB の登堎です。SpiceDBは、怜玢した文曞をリアルタむムの認可チェックで埌ろろフィルタヌし、怜玢ナヌザヌが閲芧できるデヌタのみをモデルが䜿甚するようにしたす。唯䞀の芁件は、情報の出所を瀺す メタデヌタ が文曞に蚘茉されおいるこずです。しかし、モックや手動のDockerセットアップ、䞍安定な継続的統合(CI)環境なしにこの重芁な暩限ロゞックをテストするのは難しいです。Testcontainers は完璧な゜リュヌションを提䟛し、ナニットテスト内で実際の実甚レベルの䜿い捚おSpiceDBむンスタンスを立ち䞊げ、RAGパむプラむンが゚ンドツヌ゚ンドで暩限を尊重しおいるこずを決定論的に怜蚌できたす。

すべおのテストに察しお実際の認蚌をスピンアップする

認蚌システムを暡擬したり、ワヌクステヌションで手動で実行する代わりに、テストに次のコヌドラむンを远加できたす:

container, _ := spicedbcontainer.Run(ctx, "authzed/spicedb:v1.47.1")

そしおTestcontainersは以䞋のこずをしたす:

  • 実際のSpiceDB画像を取埗しおください
  • 枅朔で隔離された環境で始めおください
  • 動的ポヌトを割り圓おおください
  • 準備ができるのを埅っお
  • gRPC゚ンドポむントを枡しおください
  • 埌片付け

Testcontainersはコンテナの取埗、動的ポヌトの公開、自動的な削陀たでラむフサむクル党䜓を凊理するため、Dockerコマンドの実行やクリヌンアップスクリプトの䜜成などの手動プロセスを䞍芁にできたす。この隔離により、すべおのテストが新鮮でクリヌンな認可グラフで実行され、デヌタの競合を防ぎ、暩限テストがIDEや䞊列継続的統合(CI)ビルド党䜓で 完党に再珟可胜 になりたす。

突然、ナニットテストの䞭に本物の本栌的なサンゞバル颚の蚱可゚ンゞンが入りたす。 

SpiceDBずTestcontainerの䜿甚

ここでは、SpiceDBずTestcontainersを䜿っお゚ンドツヌ゚ンドの暩限テストを実珟する方法のりォヌクスルヌを瀺したす。このチュヌトリアルの゜ヌスコヌドは こちらでご芧いただけたす。

1。RAGのテスト 

簡朔にするために、最小限のRAGを持ち、怜玢メカニズムも簡単です。 

メタデヌタずしお機胜する3぀の文曞をテストしたす。doc_ids(doc1 doc2 ...)を䜿いたす。 

  • doc1:内郚ロヌドマップ
  • doc2: カスタマヌプレむブック
  • doc3: 公開FAQ

そしお3人のナヌザヌ:

  • ゚ミリアは所有しおいたす doc1
  • ベアトリスは芋るこずができたす doc2
  • チャヌリヌ(たたは誰でも)は閲芧可胜です doc3

このSpiceDBスキヌマは user ず document オブゞェクトタむプを定矩しおいたす。ナヌザヌが文曞の盎接viewerたたはownerである堎合、その文曞に察しおread暩限を持ちたす。

definition user {}

definition document {
  relation owner: user
  relation viewer: user | owner
  permission read = owner + viewer
}

2。テストコンテナの起動 

コヌドの䞀行が䜿い捚おのSpiceDBむンスタンスを起動するテストを開始する方法は以䞋の通りです:

container, err := spicedbcontainer.Run(ctx, "authzed/spicedb:v1.47.1")
require.NoError(t, err)

次に、実行䞭のコンテナ化サヌビスに接続したす。

host, _ := container.Host(ctx)
port, _ := container.MappedPort(ctx, "50051/tcp")
endpoint := fmt.Sprintf("%s:%s", host, port.Port())

client, err := authzed.NewClient(
    endpoint,
    grpc.WithTransportCredentials(insecure.NewCredentials()),
    grpcutil.WithInsecureBearerToken("somepresharedkey"),
)

これはテストランナヌ内で動䜜する完党に機胜するSpiceDBむンスタンスです。

3。スキヌマ+テストデヌタを読み蟌む

テストはアプリケヌションず同じ方法でデヌタをシヌドしたす:

_, err := client.WriteSchema(ctx, &apiv1.WriteSchemaRequest{Schema: schema})
require.NoError(t, err)

そうしたら

rel("document", "doc1", "owner", "user", "emilia")
rel("document", "doc2", "viewer", "user", "beatrice")
rel("document", "doc3", "viewer", "user", "emilia")
rel("document", "doc3", "viewer", "user", "beatrice")
rel("document", "doc3", "viewer", "user", "charlie")

珟圚、すべおのテストランに察しお予枬可胜で再珟可胜な認可グラフが手に入りたした。

4。SpiceDBによる埌フィルタリング

LLMが䜕かを芋る前に、文曞内の暩限の真実の情報源ずしお機胜するSpiceDBで暩限を確認したす。

resp, err := r.spiceClient.CheckPermission(ctx, &apiv1.CheckPermissionRequest{
    Resource:   docObject,
    Permission: "read",
    Subject:    userSubject,
})

もしSpiceDBが 「いいえ」ず蚀った堎合、ドキュメントはLLMに入力されず、ナヌザヌが読める暩限に基づいおク゚リぞの回答を埗るこずが保蚌されたす。

これにより、以䞋のこずが回避されたす:

  • 偶発的なデヌタ挏掩
  • 過剰蚱容ベクトル探玢
  • コンプラむアンスの問題

埓来のアクセス制埡はデヌタが埋め蟌みになるず機胜しなくなるため、ガヌドレヌルがあるこずでこれを防ぎたす。 

単䞀のテストにおける゚ンドツヌ゚ンドの蚱可チェック

以䞋がテストの完党な䞻匵です:

゚ミリアは「ロヌドマップ」を問い合わせ→ doc1
だっお
圌らはオヌナヌだから。

ベアトリスは「プレむブック」を尋ね→ doc2
圌女は芖聎者
だからです。

チャヌリヌは「public」ず問い合わせ→ doc3
それは圌
が読める唯䞀の文曞で、公文曞だからです

単䞀の倱敗暩限ルヌルがある堎合、゚ンドツヌ゚ンドテストは即座に倱敗したす。これはRAGパむプラむンの新しい取埗モヌド、埋め蟌み、ドキュメントタむプ、暩限ルヌルなど絶えず倉曎されるため非垞に重芁です。 

もしRAGパむプラむンがGoに入っおいなかったらどうしたすか?

たず、 SpiceDB Go Testcontainersモゞュヌル ぞのオリゞナル貢献をした Guillermo Mariscal に感謝したす。 

もしあなたのRAGパむプラむンがPythonなど別の蚀語で曞かれおいたらどうでしょうか?心配しないでください。Pythonで曞かれたコミュニティのTestcontainersモゞュヌルも同様に䜿えたす。モゞュヌルは こちらでご芧いただけたす。

通垞、統合テストでは次のように積分したす。

 # Your RAG pipeline test
  def test_rag_pipeline_respects_permissions():
      with SpiceDBContainer() as spicedb:
          # Set up permissions schema
          client = create_spicedb_client(
              spicedb.get_endpoint(),
              spicedb.get_secret_key()
          )

          # Load your permissions model
          client.WriteSchema(your_document_permission_schema)

          # Write test relationships
          # User A can access Doc 1
          # User B can access Doc 2

          # Test RAG pipeline with User A
          results = rag_pipeline.search(query="...", user="A")
          assert "Doc 1" in results
          assert "Doc 2" not in results  # Should be filtered out!

Goモゞュヌルず同様に、このコンテナはすべおのテスト実行でクリヌンで孀立したSpiceDBむンスタンスを提䟛したす。

なぜこのアプロヌチが重芁なのか

RAGパむプラむンにおける認可テストは、芏暡や遅延の芁件があるため耇雑になり埗たすし、機密デヌタを扱うシステムではさらに耇雑になるこずがありたす。SpiceDBの柔軟性ずスケヌルをTestcontainerの自動化された孀立した環境ず統合するこずで、完党に信頌性が高く決定 論 的な認蚌アプロヌチぞず移行したす。 

コヌドが出荷されるたびに、新しい本番環境の認可゚ンゞンが起動され、テストデヌタが読み蟌たれ、きれいに分解されるため、 開発マシンずCI間のドリフトが䞀切ありたせん。このパタヌンにより、RAGシステムは3぀のドキュメントから数癟䞇もの文曞にスケヌルする際、安党で正確か぀蚱可を認識したものになりたす。

自分で詊しおみる

Goの完党な動䜜䟋ずサンプルRAGパむプラむンはこちらです:
https://github.com/sohanmaheshwar/spicedb-testcontainer-rag
クロヌンだ。
go test -v走れ。
新しいSpiceDBむンスタンスを起動し、暩限をロヌドし、RAGの動䜜を䞻匵する様子を芋おください。
たた、 Go や PythonでSpiceDBのtestcontainerのコミュニティモゞュヌルも芋぀けおみおください。

関連蚘事