ഫിൽറ്ററുകളും വാളുകളും (Filters and Walls) തമ്മിലുള്ള വ്യത്യാസം
നിങ്ങളുടെ ഡാറ്റ ഉപയോഗിക്കാൻ അനുമതിയുള്ള ഒരു AI ഏജന്റ് നിങ്ങൾ നിർമ്മിക്കുകയാണെന്ന് കരുതുക. സുരക്ഷയ്ക്കായി നിങ്ങൾക്ക് രണ്ട് വഴികളുണ്ട്. നിങ്ങൾക്ക് ഡാറ്റ ഫിൽറ്റർ ചെയ്യാം, അല്ലെങ്കിൽ അതിന് ചുറ്റും ഒരു മതിൽ (wall) നിർമ്മിക്കാം.
ഫിൽറ്ററിംഗ് എന്നാൽ നിങ്ങളുടെ ക്വറി (query) ചില വരികൾ മാത്രം തിരികെ നൽകുന്നു എന്നാണ് അർത്ഥം. വാളിംഗ് (Walling) എന്നാൽ ഏജന്റിന് മറച്ചുവെച്ച വരികളിലേക്ക് ഒട്ടും എത്തിച്ചേരാൻ കഴിയില്ല എന്നാണ് അർത്ഥം.
എന്തെങ്കിലും തകരാർ സംഭവിക്കുന്നത് വരെ ഇവ രണ്ടും ഒന്നുതന്നെയാണെന്ന് തോന്നും.
അടുത്തിടെ 1.2 മില്യൺ വാക്കുകളെ ഒരു നോളജ് ബേസ് (knowledge base) ആക്കി മാറ്റുന്നതിനായി ഞാൻ ഒരു സിസ്റ്റം നിർമ്മിച്ചു. ഡാറ്റ നിയന്ത്രിക്കാൻ ഞാൻ Supabase ഉപയോഗിച്ചു. എന്റെ AI ഏജന്റുകൾക്ക് പബ്ലിക് ഉള്ളടക്കം (public content) മാത്രം കാണാൻ ഞാൻ ആഗ്രഹിച്ചു.
ഡാറ്റ ഫിൽറ്റർ ചെയ്യാൻ ഞാൻ ഒരു സ്റ്റാൻഡേർഡ് Postgres view ഉപയോഗിച്ചു:
CREATE VIEW public_seeds AS
SELECT * FROM moments
WHERE visibility = 'public'
AND is_canonical = true;
ഇത് ശരിയാണെന്ന് തോന്നാം. എന്നാൽ ഇതിൽ വലിയൊരു പോരായ്മയുണ്ട്. ഡിഫോൾട്ട് ആയി, ഒരു Postgres view പ്രവർത്തിക്കുന്നത് അതിന്റെ ഉടമസ്ഥനായിട്ടാണ് (owner), അത് വിളിക്കുന്ന വ്യക്തിയായിട്ടല്ല. വ്യൂ ഉടമയ്ക്ക് പലപ്പോഴും പൂർണ്ണമായ ആക്സസ് ഉണ്ടായിരിക്കും. ഇതിനർത്ഥം നിങ്ങളുടെ Row Level Security (RLS) പോളിസികൾ ഈ വ്യൂവിൽ ബാധകമല്ല എന്നാണ്.
നിങ്ങൾ ഒരു മതിൽ നിർമ്മിച്ചതല്ല, മറിച്ച് ഒരു ഫിൽറ്റർ ആണ് നിർമ്മിച്ചത്.
ഒരു ഫിൽറ്റർ പരാജയപ്പെട്ടാൽ, ഒരു AI ഏജന്റ് അത് ശ്രദ്ധിക്കില്ല. ഒരു മനുഷ്യന് പിശകോ തെറ്റായ ഡാറ്റയോ കാണാൻ കഴിയും. എന്നാൽ ഒരു ഏജന്റ് ലഭിക്കുന്നതെന്തും പ്രോസസ്സ് ചെയ്യും. നിങ്ങളുടെ ഫിൽറ്റർ പരാജയപ്പെട്ടാൽ, മുന്നറിയിപ്പില്ലാതെ തന്നെ നിങ്ങളുടെ ഏജന്റ് സ്വകാര്യ ഡാറ്റ (private data) ഉപയോഗിക്കാൻ തുടങ്ങും.
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;
ഇപ്പോൾ മതിൽ ഘടനാപരമാണ്. ഒരു ഡെവലപ്പർ തെറ്റായ ക്വറിയോ ജോയിനോ (join) എഴുതുകയാണെങ്കിൽ പോലും, RLS പോളിസി ടേബിളിനെ സംരക്ഷിക്കുന്നു.
"ഇത് സംഭവിക്കരുത്" എന്നത് എല്ലാം കൃത്യമായി പ്രവർത്തിക്കുന്നതിനെ ആശ്രയിച്ചിരിക്കുന്നു. "ഇത് സംഭവിക്കാനാവില്ല" എന്നത് നിങ്ങളുടെ ആർക്കിടെക്ചറിനെ (architecture) ആശ്രയിച്ചിരിക്കുന്നു.
നിങ്ങൾ AI-ക്ക് വേണ്ടി നിർമ്മിക്കുമ്പോൾ, സംഭവിക്കാനേ പാടില്ലാത്ത കാര്യങ്ങൾക്കായി (what cannot happen) രൂപകൽപ്പന ചെയ്യണം.
നിങ്ങളുടെ സെറ്റപ്പിൽ പരിശോധിക്കേണ്ട മൂന്ന് കാര്യങ്ങൾ:
- ഏജന്റുകൾക്കായി നിങ്ങൾ 'service role' ഉപയോഗിക്കുന്നില്ലെന്ന് ഉറപ്പാക്കുക. service role പൂർണ്ണമായും RLS-നെ മറികടക്കുന്നു.
- നിങ്ങളുടെ Postgres വേർഷൻ പരിശോധിക്കുക.
security_invoker-ന് വേർഷൻ 15 അല്ലെങ്കിൽ അതിനു മുകളിലുള്ളത് ആവശ്യമാണ്. - നിലവിലുള്ള വ്യൂകൾ ഓഡിറ്റ് ചെയ്യുക. പഴയ വ്യൂകൾ പുതിയ RLS പോളിസികൾ സ്വയമേവ പിന്തുടരില്ല.
Optional learning community: https://t.me/GyaanSetuAi