[{"data":1,"prerenderedAt":800},["ShallowReactive",2],{"blog-uk-enable-rls-on-every-supabase-table":3,"blog-index-uk":561},{"id":4,"title":5,"body":6,"category":517,"cover":518,"coverAlt":519,"description":520,"draft":521,"extension":522,"faq":523,"image":539,"keywords":540,"meta":549,"navigation":550,"ogTitle":551,"path":552,"published":553,"seo":554,"stem":555,"tldr":556,"updated":553,"__hash__":560},"blog_uk\u002Fblog\u002Fenable-rls-on-every-supabase-table.md","Увімкніть Row Level Security на кожній таблиці Supabase і перевірте",{"type":7,"value":8,"toc":505},"minimark",[9,13,21,26,29,32,39,45,48,52,55,58,69,80,86,89,95,98,114,118,121,127,133,159,165,171,174,180,186,193,275,287,291,294,297,302,305,308,314,318,321,324,327,333,342,345,349,352,358,365,370,391,404,411,415,418,421,433,436,439,451,455,492],[10,11,12],"p",{},"Вам сказали увімкнути Row Level Security, або ваш конструктор зі ШІ згадав про\nце мимохідь, поки лагодив щось інше. У вашому проєкті Supabase десь від чотирьох\nдо сорока таблиць, і ви не знаєте, які з них закриті.",[10,14,15,16,20],{},"Інструкція, яку ви знайдете всюди, це один рядок SQL на таблицю, і настільки\nвона правильна. Те, перед чим спиняється майже кожен посібник, це наступний\nкрок. ",[17,18,19],"strong",{},"Політика, яка існує, це не політика, яка працює",", і ніщо у вашому\nдашборді не покаже вам різниці. Тож увімкнути Row Level Security у Supabase це\nтри роботи, а не одна: поставити перемикач на всіх таблицях, написати ті дві чи\nтри політики, які збирають ваш застосунок назад, а потім спитати у власної бази\nте, що спитав би в неї незнайомець.",[22,23,25],"h2",{"id":24},"що-насправді-робить-увімкнений-row-level-security","Що насправді робить увімкнений Row Level Security?",[10,27,28],{},"Змушує Postgres звірятися з вашими правилами, перш ніж віддати рядок. З\nвимкненим перемикачем звірятися немає з чим, тож відповідь на будь-який запит\nце все.",[10,30,31],{},"Уявіть бібліотекаря, який приносить те, що ви попросили. Row Level Security це\nвказівка прочитати записку про вас, перш ніж наповнювати візок. Записка це ваша\nполітика, і в ній може бути написано, що ця людина може взяти книжки, які сама\nнаписала, або що будь-хто може взяти будь-що. Якщо вказівка діє, а записки ще\nніхто не написав, бібліотекар повертається з порожнім візком і не пояснює чому.",[10,33,34,35,38],{},"Саме на цьому останньому люди й спотикаються, і саме воно вирішує, як\nвиглядатиме перевірка згодом. ",[17,36,37],{},"Row Level Security фільтрує рядки. Він не\nвідмовляє в запитах."," Таблиця, яку вам не дозволено читати, відповідає\nпорожнім списком і кодом успіху, а не помилкою чи вікном входу. Вашому\nзастосунку ніколи не кажуть, що йому відмовили. Він не отримує нічого й малює\nпорожній екран.",[40,41],"diagram",{"alt":42,"caption":43,"src":44},"Той самий запит, намальований тричі. З вимкненим перемикачем безпеки повертаються чотири підсвічені рядки. З увімкненим перемикачем і без політики повертається порожнє пунктирне місце. З увімкненим перемикачем і політикою власності повертається один підсвічений рядок. Усі три відповіді позначені 200.","Один запит, три налаштування й той самий код успіху щоразу. Row Level Security змінює те, що повертається, а не те, чи запит вдався.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fsame-request-three-answers-1600x780.png",[10,46,47],{},"Тож поставити перемикач на проєкті, у якому ще немає жодної політики, не закриє\nваші дані від незнайомців. Це закриє їх від усіх, зокрема від вашого власного\nзастосунку, доки ви не скажете, кому що можна бачити.",[22,49,51],{"id":50},"як-увімкнути-rls-на-всіх-таблицях-supabase-одразу","Як увімкнути RLS на всіх таблицях Supabase одразу?",[10,53,54],{},"Один цикл, виконаний один раз у SQL Editor. Він проходить кожну таблицю вашої\nсхеми public і вмикає перемикач скрізь, де той вимкнений.",[10,56,57],{},"Почніть із того, щоб побачити, де ви стоїте. Це виведе ваші таблиці й скаже, чи\nє перемикач у кожної просто зараз:",[59,60,65],"pre",{"className":61,"code":63,"language":64},[62],"language-text","select tablename, rowsecurity\nfrom pg_tables\nwhere schemaname = 'public'\norder by tablename;\n","text",[66,67,63],"code",{"__ignoreMap":68},"",[10,70,71,72,75,76,79],{},"Кожен рядок, де ",[66,73,74],{},"rowsecurity"," показує ",[66,77,78],{},"false",", це таблиця, яка віддає свій вміст\nбудь-кому з публічним ключем, що їде разом із вашим застосунком. Якщо список\nкороткий, робіть по одній і дивіться, що ламається:",[59,81,84],{"className":82,"code":83,"language":64},[62],"alter table public.orders enable row level security;\n",[66,85,83],{"__ignoreMap":68},[10,87,88],{},"Якщо він не короткий, це впорається з усіма:",[59,90,93],{"className":91,"code":92,"language":64},[62],"do $$\ndeclare t record;\nbegin\n  for t in\n    select tablename from pg_tables where schemaname = 'public'\n  loop\n    execute format(\n      'alter table public.%I enable row level security', t.tablename\n    );\n  end loop;\nend $$;\n",[66,94,92],{"__ignoreMap":68},[10,96,97],{},"Виконайте це, і ваш застосунок стане порожнім. Supabase прямо пише про це у\nвласній документації: дані стають недоступними через API з публічним ключем,\nдоки не визначено політики. Це перемикач робить свою роботу, і саме тому\nнаступний розділ варто мати відкритим, перш ніж тиснути виконати.",[99,100,102],"callout",{"type":101},"warn",[10,103,104,107,108,113],{},[17,105,106],{},"Таблиці, які зробив ваш конструктор, і були відкритими."," Таблиця, яку ви\nклацнули в Table Editor у Supabase, отримує увімкнений Row Level Security.\nТаблиця, створена виконанням SQL, не отримує, а виконання SQL це саме те, як\nLovable, Bolt, Cursor і v0 створюють таблиці за вас. Таблиці, народження яких ви\nніколи не бачили, і є тими, заради яких цей цикл існує, а\n",[109,110,112],"a",{"href":111},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","що ловить і чого не ловить попередження \"RLS disabled in public\"","\nпояснює, чому ваш дашборд міг про них промовчати.",[22,115,117],{"id":116},"три-політики-які-вам-справді-потрібні","Три політики, які вам справді потрібні",[10,119,120],{},"Майже кожна таблиця в застосунку на кшталт вашого має одну з трьох форм: рядки,\nякі належать одній людині, рядки, які може читати будь-хто, і рядки, які ваш\nзастосунок пише від імені відвідувача. Ось кожна з них, готова до вставляння й\nперейменування.",[10,122,123,126],{},[17,124,125],{},"Рядки, які належать одній людині."," Замовлення, повідомлення, збережені\nпозиції, усе, що має власника.",[59,128,131],{"className":129,"code":130,"language":64},[62],"create policy \"read own orders\"\non public.orders for select\nto authenticated\nusing ( (select auth.uid()) = user_id );\n",[66,132,130],{"__ignoreMap":68},[10,134,135,138,139,142,143,146,147,150,151,154,155,158],{},[66,136,137],{},"auth.uid()"," це id того, хто увійшов у цьому запиті. ",[66,140,141],{},"user_id"," це той стовпець\nвашої таблиці, у якому записаний власник, тож перевірте назву, перш ніж\nвиконувати: конструктори пишуть також ",[66,144,145],{},"owner_id",", ",[66,148,149],{},"profile_id"," і ",[66,152,153],{},"created_by",".\nРядок ",[66,156,157],{},"to authenticated"," означає, що для відвідувача без входу політику навіть\nне розглядають, і саме це тримає таблицю закритою від публіки.",[10,160,161,164],{},[17,162,163],{},"Рядки, які може читати будь-хто."," Каталог товарів, опубліковані статті, карта\nзакладів.",[59,166,169],{"className":167,"code":168,"language":64},[62],"create policy \"anyone may read products\"\non public.products for select\nto anon, authenticated\nusing ( true );\n",[66,170,168],{"__ignoreMap":68},[10,172,173],{},"Цю пишіть свідомо або не пишіть узагалі, бо це ще й та політика, за яку хапається\nконструктор зі ШІ тієї миті, коли ви просите його полагодити порожній екран.\nПитання, яке треба вирішити спершу: чи могла б ця таблиця бути сторінкою на\nвашому сайті, точно такою, як є, нічого не прибираючи? Ні означає, що їй\nпотрібна політика власності вище.",[10,175,176,179],{},[17,177,178],{},"Рядки, які пише ваш застосунок."," Читання й запис у Postgres це окремі права,\nтож таблиця, у яку ваш застосунок зберігає, потребує другої політики, і ця\nперевіряє рядок на вході, а не на виході.",[59,181,184],{"className":182,"code":183,"language":64},[62],"create policy \"insert own orders\"\non public.orders for insert\nto authenticated\nwith check ( (select auth.uid()) = user_id );\n",[66,185,183],{"__ignoreMap":68},[10,187,188,189,192],{},"Яка клауза куди йде, це та частина, на якій людей ловить, а рядок ",[66,190,191],{},"update"," несе\nвимогу, у якій немає нічого очевидного:",[194,195,196,212],"table",{},[197,198,199],"thead",{},[200,201,202,206,209],"tr",{},[203,204,205],"th",{},"Операція",[203,207,208],{},"Клауза",[203,210,211],{},"Потребує ще",[213,214,215,230,244,262],"tbody",{},[200,216,217,223,228],{},[218,219,220],"td",{},[66,221,222],{},"select",[218,224,225],{},[66,226,227],{},"using",[218,229],{},[200,231,232,237,242],{},[218,233,234],{},[66,235,236],{},"insert",[218,238,239],{},[66,240,241],{},"with check",[218,243],{},[200,245,246,250,256],{},[218,247,248],{},[66,249,191],{},[218,251,252,150,254],{},[66,253,227],{},[66,255,241],{},[218,257,258,259,261],{},"політики ",[66,260,222],{}," на тій самій таблиці",[200,263,264,269,273],{},[218,265,266],{},[66,267,268],{},"delete",[218,270,271],{},[66,272,227],{},[218,274],{},[10,276,277,278,281,282,286],{},"Документація Supabase щодо останньої однозначна: без відповідної політики select\nupdate не працює так, як ви очікуєте. А якщо сюди вас привело повідомлення\n",[66,279,280],{},"new row violates row-level security policy",", то відстань між цими двома\nклаузами і є ",[109,283,285],{"href":284},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","вся ця помилка",".",[22,288,290],{"id":289},"чому-в-кожному-прикладі-пишуть-select-authuid-а-не-authuid","Чому в кожному прикладі пишуть (select auth.uid()), а не auth.uid()",[10,292,293],{},"Бо дужки змушують Postgres обчислити значення один раз для всього запиту, а не\nодин раз для кожного рядка, який він переглядає.",[10,295,296],{},"Загорнута версія стає тим, що Postgres називає initPlan: виконується один раз, а\nдалі використовується повторно до кінця інструкції. Без дужок функцію\nвикликають знову на рядку один, на рядку два, на рядку три, і так далі вниз по\nтаблиці, у якій їх може бути сто тисяч. Власний Performance Advisor у Supabase\nповідомляє про версію без дужок за правилом під назвою Auth RLS Initialization\nPlan, і це один із записів, які там трапляються найчастіше.",[40,298],{"alt":299,"caption":300,"src":301},"Дві панелі над тими самими вісьмома рядками таблиці. На лівій панелі біля кожного рядка стоїть позначка функції з власним з'єднанням, вісім разом. На правій панелі одна позначка функції вгорі розходиться віялом до всіх восьми рядків одразу.","Дужки і є вся різниця. Ліворуч функція виконується раз на кожен рядок; праворуч вона виконується один раз, а відповідь використовується повторно.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fonce-per-query-1600x620.png",[10,303,304],{},"Одне застереження, і воно від самої Supabase: це працює тому, що відповідь не\nзмінюється від рядка до рядка. Функцію, результат якої справді залежить від\nрядка перед нею, з циклу не винести, тож саме її лишіть без дужок.",[10,306,307],{},"Поки ви тут, додайте індекс на стовпець, за яким фільтрують ваші політики.\nПолітика стає умовою на кожному читанні цієї таблиці, тож на таблиці з великою\nкількістю рядків стовпець без індексу видно у ваших часах відповіді:",[59,309,312],{"className":310,"code":311,"language":64},[62],"create index orders_user_id_idx on public.orders (user_id);\n",[66,313,311],{"__ignoreMap":68},[22,315,317],{"id":316},"перевірити-політику-не-створюючи-фальшивого-акаунта","Перевірити політику, не створюючи фальшивого акаунта",[10,319,320],{},"SQL Editor у Supabase може виконати запит так, ніби його надіслав конкретний\nвідвідувач, і це повністю покриває анонімний випадок.",[10,322,323],{},"У редакторі є елемент керування для ролі, під якою має виконуватися запит.\nПоставте його на анонімну роль, а потім виконайте звичайний select до таблиці,\nяку ви щойно змінили. Що повернеться, те й отримає незнайомець без входу. Для\nвідвідувача з входом візьміть id користувача, який у вас уже є, замість\nстворювати нового; для перевірки згодиться будь-який рядок вашої таблиці.",[10,325,326],{},"Якщо вам зручніше набрати, ніж клацнути, те саме в SQL:",[59,328,331],{"className":329,"code":330,"language":64},[62],"begin;\nset local role anon;\nselect * from public.orders;\nrollback;\n",[66,332,330],{"__ignoreMap":68},[10,334,335,150,338,341],{},[66,336,337],{},"begin",[66,339,340],{},"rollback"," стоять тут, щоб зміна ролі тривала цей блок і не довше, а це\nважить, коли ви проходите кілька таблиць за один раз.",[10,343,344],{},"Це каже вам, що ваші політики роблять усередині бази. Чого воно сказати не може,\nтак це того, що ваш проєкт віддає в інтернет, бо запит, який ваші відвідувачі\nроблять насправді, починається не в SQL Editor. Він починається в браузері,\nнесе публічний ключ і приходить через публічну адресу вашого проєкту.",[22,346,348],{"id":347},"як-перевірити-supabase-rls-ззовні-свого-застосунку","Як перевірити Supabase RLS ззовні свого застосунку?",[10,350,351],{},"Надішліть запит, який надіслав би незнайомець. Вам потрібні два значення, і\nобидва вже лежать у коді, який ваш сайт віддає кожному відвідувачу: URL вашого\nпроєкту й ваш публічний ключ.",[59,353,356],{"className":354,"code":355,"language":64},[62],"curl \"https:\u002F\u002FYOUR-PROJECT.supabase.co\u002Frest\u002Fv1\u002Forders?select=*&limit=1\" \\\n  -H \"apikey: YOUR_PUBLISHABLE_KEY\" \\\n  -H \"Authorization: Bearer YOUR_PUBLISHABLE_KEY\"\n",[66,357,355],{"__ignoreMap":68},[10,359,360,361,364],{},"Підставляйте по одній назві таблиці й читайте, що повертається. Порожній список,\n",[66,362,363],{},"[]",", означає, що політика витримала для відвідувача без входу. Рядок означає, що\nбудь-хто з ключем, який їде разом із вашим застосунком, може читати цю таблицю.\nПомилка, яка згадує сам ключ, означає, що ви скопіювали не те значення, і це\nварто виключити, перш ніж робити висновки.",[40,366],{"alt":367,"caption":368,"src":369},"Пунктирна межа навколо таблиці бази даних. Усередині біля таблиці стоїть лупа з короткою стрілкою. Ззовні людина надсилає стрілку, яка несе ключ крізь проміжок у межі, зі шляхом скісна риска rest скісна риска v1, написаним поруч із проміжком, і дістається тієї самої таблиці.","Перевірка в редакторі ніколи не виходить із будівлі. Запит ззовні приходить через ту саму публічну адресу, якою користуються ваші відвідувачі, і несе той самий ключ, що його віддає ваш застосунок.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Ftwo-tests-one-table-1600x640.png",[10,371,372,373,376,377,380,381,385,386,390],{},"У новішому проєкті Supabase цей ключ починається з ",[66,374,375],{},"sb_publishable_",", а в\nстарішому це ключ ",[66,378,379],{},"anon",". Обидва безпечно так використовувати й безпечно тримати\nу вашому застосунку, у цьому й полягає їхнє призначення;\n",[109,382,384],{"href":383},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","які API-ключі належать фронтенду","\nрозбирає ту пару, яка не належить, а\n",[109,387,389],{"href":388},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","де знайти їх у дашборді"," це чотири\nзначення на тій сторінці налаштувань.",[10,392,393,394,398,399,403],{},"Це та перевірка, яка відповідає дійсності, і саме тому, що ми прогнали її у\nвеликому масштабі, ми знаємо, наскільки ця прогалина поширена. Між 12 і 14\nсерпня 2026 року ми прогнали дев'ять зовнішніх перевірок по 30 998 живих\nзастосунках, опублікованих із Lovable, Base44, Replit, v0 і Bolt. Із 3 680\nзастосунків на Supabase, де перевірка дійшла до кінця, 2 096 відповіли на\nанонімний запит рядками щонайменше з однієї таблиці. Це 57 %, і це частка від\nзастосунків, від яких ми отримали чітку відповідь, а не від усього, що ми\nпросканували. ",[109,395,397],{"href":396},"\u002Fresearch\u002Fvibe-coded-app-security-2026","Повний набір даних опубліковано",",\nа ",[109,400,402],{"href":401},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","від чого ці 57 % є часткою","\nпроходить підрахунок.",[10,405,406,407,286],{},"Робити це руками нормально для чотирьох таблиць і виснажливо для сорока. Наше\nбезкоштовне сканування надсилає цей запит за вас, з'ясовує, які таблиці існують,\nбез того щоб ви їх називали, і каже, які відповіли, поряд із вісьмома іншими\nперевірками, які воно робить ззовні. Воно читає ваш живий сайт так само, як може\nбудь-який відвідувач, триває близько 20 секунд і не потребує акаунта:\n",[109,408,410],{"href":409},"\u002Fsecurity-scanner","просканувати застосунок",[22,412,414],{"id":413},"перш-ніж-переписувати-політики-на-живій-таблиці","Перш ніж переписувати політики на живій таблиці",[10,416,417],{},"Спершу зробіть копію своєї бази. Ви збираєтеся змінити права на всіх таблицях,\nякі маєте, тими самими інструментами, що створили проблему.",[10,419,420],{},"Варто розділити два різні ризики, бо лише один із них стосується сьогоднішньої\nроботи. Якщо таблицю міг читати й змінювати будь-хто, то закрити її зараз нічого\nне змінить у тому, що вже сталося, і ця версія зазвичай спливає як звернення до\nпідтримки про дані, які змінилися самі. Другий ризик це сама міграція. Політика,\nяку видалили й трохи криво створили заново, це звичайний вівторок, а шлях назад\nце копія того, як усе виглядало годину тому.",[10,422,423,424,428,429,286],{},"На платному тарифі Supabase учорашня копія чекає в консолі. На безкоштовному\nтарифі відступати немає куди взагалі, бо\n",[109,425,427],{"href":426},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Supabase не робить жодних автоматичних резервних копій на безкоштовному тарифі",".\nЯкщо це про вас,\n",[109,430,432],{"href":431},"\u002Fblog\u002Fback-up-supabase-free-tier","зробіть копію, перш ніж починати",[10,434,435],{},"Reeve Care це та версія цього, про яку вам не треба пам'ятати. Вашу базу\nSupabase копіюють за розкладом, тримають поза вашим акаунтом Supabase,\nзашифрованою, і зчитують назад, щоб підтвердити, що вона відновлюється, перш ніж\nдата на вашому дашборді зрушить. Завантажені файли їдуть разом із нею, щойно ви\nпід'єднаєте ключ Storage, і цей ключ просять окремо, бо Supabase не видає ключа\nтільки для читання для файлів: той, що копіює ваші завантаження, вміє й писати,\nа той, що копіює вашу базу, не вміє. Під'єднувати його необов'язково, і базу\nрезервують у будь-якому разі. Резервні копії лише для Supabase, тож якщо ваші\nдані живуть деінде, ми так і кажемо, замість продавати підписку, яка стереже\nпорожню коробку.",[10,437,438],{},"Відновлення це та частина, яка важить у такий день, як цей. Care копіює поточний\nстан вашої бази, перш ніж програти ту версію, яку ви обрали, тож натискання\nкнопки має власне скасування.",[10,440,441,442,446,447,286],{},"Друга половина це та перевірка, яку ви щойно зробили руками. Політику, яка\nпослабилася під час якоїсь пізнішої міграції, ніхто не знайде поглядом, тож Care\nпрогонить той самий анонімний запит знову за розкладом і скаже вам, коли почне\nвідповідати таблиця, яка минулого тижня мовчала. Моніторинг доступності та\nщомісячний звіт входять у ту саму підписку. Ніщо з цього не напише ваші політики\nза вас, і жодна резервна копія не закриє відкриту таблицю. Змінюється те,\nскільки коштуватиме вам міграція, що пішла не так.\n",[109,443,445],{"href":444},"\u002Fsupabase-backups","Що Reeve резервує в Supabase, як часто, і що робить відновлення","\nпроходить увесь цикл, а тарифи є на\n",[109,448,450],{"href":449},"\u002Fpricing","сторінці цін",[22,452,454],{"id":453},"порядок-у-якому-працювати","Порядок, у якому працювати",[456,457,458],"key-takeaways",{},[459,460,461,469,472,479,489],"ul",{},[462,463,464,465,468],"li",{},"Виведіть свої таблиці через ",[66,466,467],{},"select tablename, rowsecurity from pg_tables where schemaname = 'public'"," і подивіться, скільки з них відкриті, перш ніж щось міняти.",[462,470,471],{},"Зробіть резервну копію, а потім увімкніть Row Level Security на кожній таблиці схеми public. Очікуйте, що застосунок стане порожнім; це перемикач робить свою роботу.",[462,473,474,475,478],{},"Дайте кожній таблиці одну з трьох політик. Власність це типовий випадок; ",[66,476,477],{},"USING (true)"," це рішення, яке ви приймаєте таблиця за таблицею, а не спосіб повернути екрани.",[462,480,481,482,485,486,488],{},"Пишіть ",[66,483,484],{},"(select auth.uid())",", а не ",[66,487,137],{},", і додайте індекс на стовпець, за яким фільтрують ваші політики.",[462,490,491],{},"Перевірте кожну таблицю ззовні й без входу. Порожній список це залік. Рядок це таблиця, яку може прочитати будь-хто, хоч би що казав ваш дашборд.",[10,493,494,495,499,500,504],{},"Почніть із тієї таблиці, за яку вам було б найсоромніше як за публічну сторінку,\nі спускайтеся звідти вниз.\n",[109,496,498],{"href":497},"\u002Fchecklist","10-хвилинний чекліст безпеки"," охоплює це разом з рештою того, що\nварто підтвердити у щойно запущеному застосунку, а\n",[109,501,503],{"href":502},"\u002Fis-your-supabase-app-safe","посібник з безпеки Supabase"," проходить по тому, що\nще схильне лишатися відкритим.",{"title":68,"searchDepth":506,"depth":506,"links":507},3,[508,510,511,512,513,514,515,516],{"id":24,"depth":509,"text":25},2,{"id":50,"depth":509,"text":51},{"id":116,"depth":509,"text":117},{"id":289,"depth":509,"text":290},{"id":316,"depth":509,"text":317},{"id":347,"depth":509,"text":348},{"id":413,"depth":509,"text":414},{"id":453,"depth":509,"text":454},"Основи безпеки","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcover-1200x630.png","Список таблиць бази даних на панелі, біля кожної перемикач безпеки, і більшість із них досі вимкнені.","Row Level Security у Supabase без політики закриває таблицю повністю. Політика без увімкненого перемикача не робить нічого. Ось SQL, і ось перевірка.",false,"md",[524,527,530,533,536],{"q":525,"a":526},"Що станеться, якщо я увімкну RLS і не напишу жодної політики?","Таблиця перестане відповідати, зокрема й вашому власному застосунку. З увімкненим перемикачем Postgres звіряється з вашими політиками, перш ніж віддати рядок, а без політик немає нічого, що могло б сказати так, тож запити повертаються порожніми. Supabase пише про це прямо: дані стають недоступними через API з публічним ключем, доки не визначено політики. Нічого не видаляється і нічого не ламається. Напишіть політику для тих рядків, які ваш застосунок має показувати, і екрани повернуться.",{"q":528,"a":529},"Чи сповільнює Row Level Security мої запити?","Може сповільнювати, і обидва виправлення невеликі. Пишіть `(select auth.uid())` в умові політики, з дужками, щоб Postgres обчислив значення один раз для всього запиту й далі використовував його для кожного рядка. Supabase позначає версію без дужок у власному Performance Advisor, за правилом під назвою Auth RLS Initialization Plan. Далі додайте індекс на стовпець, за яким фільтрує політика, зазвичай це `user_id`. На таблиці в кілька тисяч рядків ви навряд чи помітите різницю. На великій важить і те, і те.",{"q":531,"a":532},"Чи потрібен RLS, якщо в таблиці немає персональних даних?","Увімкненим його все одно варто мати, а політика може бути дозвільною. Таблицю з вимкненим Row Level Security може прочитати будь-хто з публічним ключем, який їде разом із вашим застосунком, і це нормально для каталогу товарів та значно менш нормально для всього, що ви не опублікували б окремою сторінкою. Увімкнути його й написати політику читання з `USING (true)` дає той самий публічний доступ, але свідомо, і наступного разу, коли хтось переглядатиме список, ця таблиця читатиметься як вирішена, а не як забута.",{"q":534,"a":535},"Чому моя realtime-підписка перестала працювати після увімкнення RLS?","Бо Realtime звіряється з тими самими політиками, перш ніж надіслати зміну підписнику. Таблиця з увімкненим Row Level Security і без політики select для цього відвідувача не віддає рядків запиту й не віддає змін підписці, рівно з тієї самої причини. Додайте політику select, потрібну цій підписці, і потік відновиться. Якщо ви користуєтеся Realtime broadcast чи presence, а не змінами в базі, вони авторизуються окремо, політиками на таблиці `realtime.messages`.",{"q":537,"a":538},"Як перевірити політику, не створюючи фальшивого користувача?","Двома способами, і жоден не потребує нового акаунта. SQL Editor у Supabase може виконати запит так, ніби його надіслала конкретна роль, і це повністю покриває анонімний випадок: що повернеться, те й отримає незнайомець. Для випадку з входом потрібен id користувача як дублер, і згодиться будь-який рядок, який уже є у вашій таблиці. Другий спосіб це запит ззовні з вашим публічним ключем, який перевіряє весь шлях, а не саму лише політику.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",[541,542,543,544,545,546,547,548],"увімкнути row level security supabase","supabase увімкнути rls","row level security policies supabase","приклад політики rls supabase","supabase rls select auth.uid","перевірити rls supabase","supabase rls best practices","auth.uid() policy",{},true,"Увімкніть Row Level Security на кожній таблиці Supabase","\u002Fblog\u002Fenable-rls-on-every-supabase-table","2026-09-10",{"title":5,"description":520},"blog\u002Fenable-rls-on-every-supabase-table",[557,558,559],"Увімкнути Row Level Security у Supabase без політики означає закрити таблицю повністю, а написати політику, не увімкнувши перемикач, означає не зробити нічого. Кожній таблиці потрібне і те, і те.","Три форми політик покривають майже все, що створює конструктор зі ШІ: рядки, які належать одній людині, рядки, які може читати будь-хто, і рядки, які ваш застосунок пише від імені відвідувача.","Далі перевірте ззовні свого застосунку й без входу, бо саме такий запит робить незнайомець, і лише він каже вам, що ваші політики роблять, а не що вони обіцяють.","oKUtl-7Qxbk57kpqW3QG4Xp9F73Lcb-the__LhHgXX0",[562,569,575,581,587,593,599,605,611,617,623,629,635,641,642,647,653,659,665,671,677,683,689,695,701,706,712,717,722,728,734,740,746,752,758,763,768,774,779,785,790,796],{"path":563,"title":564,"description":565,"published":566,"category":567,"image":568,"draft":521},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":570,"title":571,"description":572,"published":573,"category":517,"image":574,"draft":521},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":576,"title":577,"description":578,"published":579,"category":517,"image":580,"draft":521},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":582,"title":583,"description":584,"published":585,"category":517,"image":586,"draft":521},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":588,"title":589,"description":590,"published":591,"category":517,"image":592,"draft":521},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":594,"title":595,"description":596,"published":597,"category":517,"image":598,"draft":521},"\u002Fblog\u002Fvite-and-next-public-env-vars","Змінні оточення Vite відкриті: префікс означає опублікувати це","Змінні оточення Vite відкриті у вашому застосунку, бо так просив префікс. VITE_ і NEXT_PUBLIC_ означають опублікувати це, а ШІ, який їх додав, не знав ціни.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":600,"title":601,"description":602,"published":603,"category":517,"image":604,"draft":521},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":606,"title":607,"description":608,"published":609,"category":517,"image":610,"draft":521},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":612,"title":613,"description":614,"published":615,"category":517,"image":616,"draft":521},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":618,"title":619,"description":620,"published":621,"category":567,"image":622,"draft":521},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":624,"title":625,"description":626,"published":627,"category":567,"image":628,"draft":521},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery у Supabase: ціна та межі","Point-in-time recovery у Supabase відмотує базу на будь-яку секунду за останній тиждень. Коштує $100 на місяць понад Pro і покриває лише базу даних.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":630,"title":631,"description":632,"published":633,"category":567,"image":634,"draft":521},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":636,"title":637,"description":638,"published":639,"category":517,"image":640,"draft":521},"\u002Fblog\u002Fsafest-ai-app-builder","Який білдер застосунків з ШІ найбезпечніший? 30 998 тестів","Який білдер застосунків з ШІ найбезпечніший? Ми просканували 30 998 живих застосунків з Lovable, Base44, Replit, v0 і Bolt. Оцінку вирішує не білдер.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":552,"title":5,"description":520,"published":553,"category":517,"image":539,"draft":521},{"path":111,"title":643,"description":644,"published":645,"category":517,"image":646,"draft":521},"Supabase \"RLS disabled in public\": чого не бачить попередження","Supabase позначає \"RLS disabled in public\" як помилку. Про політику читання, яка лишає вашу таблицю так само відкритою, він не каже нічого.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":648,"title":649,"description":650,"published":651,"category":517,"image":652,"draft":521},"\u002Fblog\u002Frotate-supabase-service-role-key","Як замінити злитий ключ service_role у Supabase","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":654,"title":655,"description":656,"published":657,"category":517,"image":658,"draft":521},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Десять інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":660,"title":661,"description":662,"published":663,"category":517,"image":664,"draft":521},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":666,"title":667,"description":668,"published":669,"category":517,"image":670,"draft":521},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":672,"title":673,"description":674,"published":675,"category":517,"image":676,"draft":521},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":678,"title":679,"description":680,"published":681,"category":517,"image":682,"draft":521},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Ваш ключ API OpenAI відкритий у фронтенді. Замініть його.","Ключ API OpenAI, відкритий у фронтенді, не можна прив'язати до домену. Замініть його сьогодні, перенесіть виклик на свій сервер і обмежте витрати.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":684,"title":685,"description":686,"published":687,"category":517,"image":688,"draft":521},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Ключ API у фронтенді: що насправді віддають 30 998 застосунків","Ключ API, відкритий у вашому фронтенді, зазвичай є ключем Google Maps. Ми просканували 30 998 vibe-coded застосунків і порахували, що витікає насправді.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":690,"title":691,"description":692,"published":693,"category":567,"image":694,"draft":521},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":696,"title":697,"description":698,"published":699,"category":517,"image":700,"draft":521},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":431,"title":702,"description":703,"published":704,"category":567,"image":705,"draft":521},"Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":707,"title":708,"description":709,"published":710,"category":517,"image":711,"draft":521},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":388,"title":713,"description":714,"published":715,"category":517,"image":716,"draft":521},"Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":284,"title":718,"description":719,"published":720,"category":517,"image":721,"draft":521},"New row violates row-level security policy в Supabase. Що далі?","\"New row violates row-level security policy\" означає, що Supabase відмовив у записі. Швидке виправлення знову відкриває таблицю для всіх.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":723,"title":724,"description":725,"published":726,"category":517,"image":727,"draft":521},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":729,"title":730,"description":731,"published":732,"category":567,"image":733,"draft":521},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching у Supabase це не бекап. Він іде тільки вперед.","Чому branching у Supabase це не бекап: гілка стартує без ваших даних, а мердж переносить саму лише схему. Для чого він потрібен і що брати замість нього.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":735,"title":736,"description":737,"published":738,"category":567,"image":739,"draft":521},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":741,"title":742,"description":743,"published":744,"category":517,"image":745,"draft":521},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":747,"title":748,"description":749,"published":750,"category":517,"image":751,"draft":521},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Чи є проблемою ключ API Google у вашому браузері?","Ключ API Google у відкритому коді сторінки наш сканер знаходить найчастіше, і зазвичай усе гаразд. Вирішує це одне безкоштовне налаштування.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":753,"title":754,"description":755,"published":756,"category":567,"image":757,"draft":521},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":401,"title":759,"description":760,"published":761,"category":517,"image":762,"draft":521},"Чи може будь-хто прочитати вашу базу Supabase? 3 680 застосунків","Чи може будь-хто прочитати вашу базу даних Supabase без входу? Ми просканували 30 998 живих застосунків, зроблених ШІ-білдерами, і виміряли, як часто так.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":764,"title":765,"description":766,"published":761,"category":517,"image":767,"draft":521},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":769,"title":770,"description":771,"published":772,"category":517,"image":773,"draft":521},"\u002Fblog\u002Fsupabase-new-api-keys","Нові API-ключі Supabase: який із них безпечний у застосунку?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":426,"title":775,"description":776,"published":777,"category":567,"image":778,"draft":521},"Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":780,"title":781,"description":782,"published":783,"category":517,"image":784,"draft":521},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security увімкнено. Таблиця досі публічна.","Увімкнути Supabase Row Level Security не означає захистити таблицю. Захищають політики, а та, що полагодила застосунок, часто впускає всіх.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":786,"title":787,"description":788,"published":783,"category":567,"image":789,"draft":521},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":567,"image":795,"draft":521},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Три способи зробити резервну копію бази Supabase, і чого бракує","Панель, pg_dump і керований сервіс. Що насправді зберігає кожен спосіб, що тихо лишає осторонь і який із них переживе втрату акаунта.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":383,"title":797,"description":798,"published":794,"category":517,"image":799,"draft":521},"Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1790150956269]