
در این مقاله
در RAG چندمشتری، پیدا کردن نزدیکترین متن کافی نیست؛ باید فقط از اسنادی پاسخ بسازید که کاربر اجازه خواندنشان را دارد. اگر یک مشتری بتواند با سؤال مشابه، بخشی از سند مشتری دیگر را بازیابی کند، کیفیت مدل یا دقت جستوجوی برداری مشکل را جبران نمیکند. مرز دسترسی باید پیش از ساخت Context و قبل از ارسال متن به مدل اعمال شود.
سناریوی این راهنما یک سامانه پشتیبانی با دو سازمان ساختگی است. هر سازمان چند سند دارد و یک کاربر ممکن است فقط به بخشی از اسناد همان سازمان دسترسی داشته باشد. از PostgreSQL RLS برای یک لایه کنترل استفاده میکنیم، اما آن را جای احراز هویت، مجوز سند یا کنترل فایل نمیدانیم. نمونه آموزشی باید روی دیتابیس آزمایشی اجرا شود، نه روی داده مشتری.
سه مرز مستقل: هویت، سازمان و سند
هویت میگوید چه کسی درخواست داده است. عضویت سازمان مشخص میکند در کدام فضای کاری عمل میکند. مجوز سند تعیین میکند در همان فضا چه محتوایی برای او مجاز است. یک tenant_id بهتنهایی هر سه مسئله را حل نمیکند. شناسه سازمانی که مرورگر میفرستد باید در سرور با عضویت معتبر تطبیق داده شود، نه اینکه مستقیم به فیلتر جستوجو تبدیل شود.
مراحل پایه در آموزش RAG با Embedding و pgvector آمده است. این مقاله روی بخش امنیتی عمیقتر میشود: داده ورودی چگونه برچسب میخورد، نقش دیتابیس چه میبیند و خروجی بازیابی چگونه به پاسخ و استناد تبدیل میشود. قبل از بحث مدل، یک پاسخ ساده به این پرسش لازم است: آیا همین کاربر میتواند سند مرجع را مستقل از چت باز کند؟
نقشه داده را پیش از افزودن بردار طراحی کنید
برای فایل اصلی، متن استخراجشده، Chunk، بردار، نتیجه جستوجو و پاسخ ذخیرهشده مالک مشخص تعریف کنید. حذف سند باید به داده مشتقشده هم برسد و تغییر مجوز باید روی بازیابی بعدی اثر بگذارد. اگر فقط فایل اصلی حذف شود اما متن Chunk در کش بماند، داده هنوز قابل افشا است. این زنجیره را با شناسه سند پایدار قابل پیگیری کنید.
Embedding رمزگذاری یا ناشناسسازی نیست. بردار هم از داده متن مشتق شده و باید تحت همان سیاست نگهداری قرار گیرد. برای انتخاب مدل، Embedding API پاستا و ابعاد مدل فعال را بررسی کنید. کلید ارائهدهنده را در بکاند نگه دارید؛ پاسخ مدل یا سرویس بردارسازی، مالکیت داده و مجوز کاربر را برای برنامه شما تعیین نمیکند.
RLS چه کاری میکند و کجا کافی نیست؟
در PostgreSQL، سیاست امنیت سطر میتواند دیدن یا نوشتن ردیفها را برای نقشهای مشمول محدود کند. مستندات رسمی Row Security درباره رفتار مالک جدول، نقشهای ویژه و حالت نبود سیاست توضیح میدهد. برنامه نباید برای راحتی با superuser یا نقش دارای BYPASSRLS اجرا شود. موفقیت آزمون با مدیر، شاهد امنیت نقش واقعی برنامه نیست.
RLS فایل خارج از دیتابیس، لینک دانلود عمومی، لاگ یا کش پاسخ را محافظت نمیکند. همچنین مجوز داخل یک سازمان ممکن است به کاربر، گروه یا وضعیت انتشار سند وابسته باشد. سیاست سازمانی ساده زیر فقط برای نشاندادن جداسازی دو سازمان است. در محصول واقعی باید شرایط دسترسی سند را در همان مسیر معتبر اضافه کنید و آزمونهای آن را مستقل بنویسید.
یک سیاست کوچک برای پروژه آزمایشی
نمونه زیر طرح پایه را نشان میدهد. نام Schema و جدول را برای محیط آزمایشی خودتان انتخاب کنید و تغییر را با نقش مهاجرت مجاز انجام دهید. نقش سرویس باید فقط دسترسی لازم را داشته باشد و مالک یا مدیر عمومی نباشد. فعالکردن FORCE نیز نقشهای ویژه را به نقش عادی تبدیل نمیکند؛ ویژگی نقش واقعی را جدا بررسی کنید.
CREATE TABLE rag_demo_chunks (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
tenant_id uuid NOT NULL,
document_id uuid NOT NULL,
body text NOT NULL
);
ALTER TABLE rag_demo_chunks ENABLE ROW LEVEL SECURITY;
ALTER TABLE rag_demo_chunks FORCE ROW LEVEL SECURITY;
CREATE POLICY tenant_scope ON rag_demo_chunks
USING (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::uuid)
WITH CHECK (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::uuid);
تنظیم app.tenant_id در این الگو فقط وقتی مرز مفیدی است که اتصال دیتابیس و اجرای SQL در اختیار بکاند مورد اعتماد باشند. اگر کاربر بتواند SQL دلخواه اجرا کند یا Credential این نقش را داشته باشد، خودش میتواند تنظیم را تغییر دهد. RLS مبتنی بر Context، جای جلوگیری از SQL Injection، مدیریت اتصال و حفاظت از رمز سرویس را نمیگیرد.


نظرات کاربران (۰)
هنوز نظری ثبت نشده است. اولین نفر باشید.