पाठ 19 / 28

RAG Access Control और Vector Store सुरक्षा

Retrieval को अनुमतियों का सम्मान करवाएँ और embeddings की रक्षा करें।

Prompt से पहले filter करें, बाद में नहीं

RAG सहायक आपके दस्तावेज़ खोजता है और सबसे अच्छे अंश मॉडल को देता है। खोज index सबके दस्तावेज़ कवर करे और कोई जाँच न करे कि कौन पूछ रहा है, तो user ऐसा दस्तावेज़ retrieve कर सकता है (और मॉडल उद्धृत कर सकता है) जिसे देखने का उसे अधिकार नहीं: वेतन, अन्य ग्राहकों के records, गोपनीय योजनाएँ। उपाय retrieval के भीतर access control है: हर chunk के साथ metadata में अनुमतियाँ (tenant, groups, दस्तावेज़ ACLs) जोड़ें और खोज query में ही वर्तमान user के लिए filter लगाएँ, ताकि निषिद्ध chunks prompt तक कभी न पहुँचें। पहले retrieve करके यह आशा न रखें कि मॉडल पाठ रोक लेगा; पाठ prompt में आ गया तो लीक हो सकता है। Vector store की भी रक्षा करें (authentication, network अलगाव, encryption), याद रखें कि embeddings अपने स्रोत पाठ के बारे में जानकारी लीक कर सकते हैं, और index को deletions व अनुमति बदलावों के साथ तालमेल में रखें।

पहले filter बनाम कोई filter नहीं, चलाकर

मैंने यह सादे Python 3 (सिर्फ़ standard library) से चलाया। यहाँ सारे हमले स्थानीय डेटा पर हानिरहित प्रदर्शन हैं, कोई असली system उपयोग नहीं हुआ। वेतन का सवाल दस्तावेज़ 1, 2 और 3 retrieve करता है। Retrieval के भीतर filtering के साथ engineer को सिर्फ़ 1 और 3 मिलते हैं; filtering के बिना सिर्फ़-HR वेतन दस्तावेज़ 2 prompt में आ जाता है। HR user को वैध रूप से तीनों मिलते हैं।

DOCS = [
    {"id": 1, "text": "Public refund policy", "allowed": {"everyone"}},
    {"id": 2, "text": "Salary bands (HR only)", "allowed": {"hr"}},
    {"id": 3, "text": "Engineering roadmap", "allowed": {"eng", "hr"}},
]
def retrieve(query_hits, user_groups, filter_first):
    if filter_first:                                           # enforce access control INSIDE retrieval
        visible = [d for d in DOCS if d["allowed"] & (user_groups | {"everyone"})]
        return [d["id"] for d in visible if d["id"] in query_hits]
    return query_hits                                          # MISTAKE: everything retrieved goes into the prompt

hits = [1, 2, 3]                                               # what similarity search found for a salary question
print("engineer, filter first :", retrieve(hits, {"eng"}, True))
print("engineer, no filter    :", retrieve(hits, {"eng"}, False), "  <- salary document leaks into the prompt")
print("hr user, filter first  :", retrieve(hits, {"hr"}, True))

Output:

engineer, filter first : [1, 3]
engineer, no filter    : [1, 2, 3]   <- salary document leaks into the prompt
hr user, filter first  : [1, 2, 3]

दो users से परखें

स्वचालित जाँच रखें कि user A कभी user B के दस्तावेज़ retrieve नहीं कर सकता।

त्वरित जाँच: RAG अनुमतियाँ कहाँ लागू होनी चाहिए?

  • कहीं नहीं
  • सिर्फ़ मॉडल से secrets छिपाने को कहकर
  • सिर्फ़ UI में
  • Retrieval query में, ताकि निषिद्ध पाठ prompt में कभी न आए
Answer

Retrieval query में, ताकि निषिद्ध पाठ prompt में कभी न आए — पाठ prompt में आ गया तो आप मॉडल से उसे निजी रखने पर निर्भर नहीं रह सकते।