𝗧𝗵𝗲 𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝗰𝗲 𝗕𝗲𝘁𝘄𝗲𝗲𝗻 𝗙𝗶𝗹𝘁𝗲𝗿𝘀 𝗮𝗻𝗱 𝗪𝗮𝗹𝗹𝘀
आप अपने डेटा तक पहुँच रखने वाला एक AI एजेंट बना रहे हैं। सुरक्षा के लिए आपके पास दो विकल्प हैं। आप डेटा को फ़िल्टर कर सकते हैं, या आप उसे 'वॉल' (wall) कर सकते हैं।
फ़िल्टरिंग का मतलब है कि आपकी क्वेरी केवल कुछ चुनिंदा पंक्तियों (rows) को ही वापस लाती है। वॉलिंग का मतलब है कि एजेंट छिपी हुई पंक्तियों तक पहुँच ही नहीं सकता।
ये दोनों एक जैसे ही लगते हैं, जब तक कि कुछ गड़बड़ न हो जाए।
मैंने हाल ही में 1.2 मिलियन शब्दों को एक नॉलेज बेस (knowledge base) में बदलने के लिए एक सिस्टम बनाया। मैंने डेटा को मैनेज करने के लिए Supabase का उपयोग किया। मैं चाहता था कि मेरे AI एजेंट केवल सार्वजनिक (public) कंटेंट ही देख सकें।
मैंने डेटा को फ़िल्टर करने के लिए एक स्टैंडर्ड Postgres view का उपयोग किया:
CREATE VIEW public_seeds AS
SELECT * FROM moments
WHERE visibility = 'public'
AND is_canonical = true;
यह सही लगता है। लेकिन इसमें एक बड़ी खामी है। डिफ़ॉल्ट रूप से, एक Postgres view 'ओनर' (owner) के रूप में चलता है, न कि उसे कॉल करने वाले व्यक्ति के रूप में। व्यू ओनर के पास अक्सर पूर्ण एक्सेस होता है। इसका मतलब है कि आपकी Row Level Security (RLS) नीतियां इस व्यू पर लागू नहीं होती हैं।
आपने दीवार (wall) नहीं बनाई। आपने केवल एक फ़िल्टर बनाया है।
यदि फ़िल्टर विफल हो जाता है, तो AI एजेंट को इसका पता नहीं चलेगा। एक इंसान त्रुटि (error) या गलत डेटा देख सकता है। एक एजेंट बस वही प्रोसेस करता है जो उसे प्राप्त होता है। यदि आपका फ़िल्टर विफल हो जाता है, तो आपका एजेंट बिना किसी चेतावनी के निजी डेटा का उपयोग करना शुरू कर देगा।
Postgres 15 ने security_invoker विकल्प के साथ इस समस्या को हल कर दिया है।
जब आप security_invoker को true पर सेट करते हैं, तो व्यू 'कॉलिंग रोल' (calling role) के रूप में चलता है। यह व्यू को आपकी RLS नीतियों का पालन करने के लिए मजबूर करता है। व्यू एक संरचनात्मक गेट (structural gate) बन जाता है।
सही तरीका:
CREATE VIEW public_seeds
WITH (security_invoker = true)
AS
SELECT * FROM moments
WHERE visibility = 'public'
AND is_canonical = true;
अब दीवार संरचनात्मक (structural) है। भले ही कोई डेवलपर कोई गलत क्वेरी या जॉइन (join) लिखे, RLS नीति टेबल की रक्षा करती है।
"ऐसा नहीं होना चाहिए" (This should not happen) इस बात पर निर्भर करता है कि सब कुछ पूरी तरह से काम कर रहा है। "ऐसा नहीं हो सकता" (This cannot happen) आपकी आर्किटेक्चर (architecture) पर निर्भर करता है।
जब आप AI के लिए निर्माण करते हैं, तो आपको उस चीज़ के लिए डिज़ाइन करना चाहिए जो "नहीं हो सकती"।
अपने सेटअप में जाँचने योग्य तीन चीजें:
- सुनिश्चित करें कि आप एजेंटों के लिए 'service role' का उपयोग नहीं कर रहे हैं। 'service role' पूरी तरह से RLS को बायपास कर देता है।
- अपना Postgres वर्शन चेक करें।
security_invokerके लिए आपको वर्शन 15 या उससे ऊपर की आवश्यकता है। - अपने मौजूदा व्यूज़ का ऑडिट करें। पुराने व्यूज़ स्वचालित रूप से नई RLS नीतियों का पालन नहीं करते हैं।
Optional learning community: https://t.me/GyaanSetuAi