[{"data":1,"prerenderedAt":917},["ShallowReactive",2],{"blog-uk-no-api-key-found-in-request":3,"blog-index-uk":564},{"id":4,"title":5,"body":6,"category":521,"cover":522,"coverAlt":523,"description":524,"draft":525,"extension":526,"faq":527,"image":543,"keywords":544,"meta":552,"navigation":553,"ogTitle":554,"path":555,"published":556,"seo":557,"stem":558,"tldr":559,"updated":556,"__hash__":563},"blog_uk\u002Fblog\u002Fno-api-key-found-in-request.md","\"No API key found in request\" у Supabase, і хибне виправлення",{"type":7,"value":8,"toc":508},"minimark",[9,13,24,27,35,40,43,50,53,56,62,66,69,85,102,108,118,122,127,133,143,151,155,158,161,175,192,195,200,204,207,210,277,280,283,290,297,304,309,316,320,323,332,339,345,357,376,380,383,392,400,404,410,419,435,445,462,466,495],[10,11,12],"p",{},"Учора ваш застосунок працював. Сьогодні список, який зазвичай наповнювався\nрядками, лишається порожнім, а якщо відкрити консоль браузера, там замість даних\nстоїть коротка відповідь від Supabase:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","{\n  \"message\": \"No API key found in request\",\n  \"hint\": \"No `apikey` request header or url param was found.\"\n}\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26],{},"Це все, що ви отримуєте. Тут не сказано, яку таблицю ви читали, що надіслали й\nщо змінювати.",[10,28,29,30,34],{},"Ось те, що посібник за посібником переказує неправильно: ",[31,32,33],"strong",{},"\"No API key found in\nrequest\" про заголовок, якого бракує, а більшість порад, які ви знайдете, про\nправила вашої бази даних."," На форумі обговорень Supabase це повідомлення має\nвласну гілку, шістнадцять людей пропонують там вісім різних засобів, і троє з\nних радять додати або послабити правило на одній із ваших таблиць. Усі, хто\nспробував, кажуть, що повідомлення припинилося. Чи було правило колись причиною\nце інше питання, і гілка його ніколи не закриває. Напевно відомо лише те, що\nпісля цього таблицю може читати більше людей, ніж раніше.",[36,37,39],"h2",{"id":38},"що-означає-no-api-key-found-in-request","Що означає \"No API key found in request\"",[10,41,42],{},"Supabase розвернув ваш запит на вході, перш ніж у вашої бази даних щось\nзапитали.",[10,44,45,46,49],{},"Кожен запит до вашого проєкту спершу приходить до брами, яку Supabase ставить\nперед усім іншим. Її робота в ту мить вузька: прочитати заголовок ",[21,47,48],{},"apikey",",\nзвірити значення з ключами вашого проєкту й пропустити запит далі. Коли читати\nнічого, вона зупиняється там і відповідає 401, кодом стану для «я не знаю, хто\nви». Довідка Supabase про цю браму сама каже, що відсутній або недійсний ключ\nвідхиляють саме так.",[10,51,52],{},"Уявіть браму як вахтера біля вхідних дверей, а не як замок на шафі з\nдокументами. Вахтер просить перепустку в кожного, хто приходить. Правила, які\nвирішують, кому яку шафу відчиняти, лежать двома поверхами вище, і тут до них\nніхто не звертався, бо далі входу ніщо не пройшло.",[10,54,55],{},"Як на помилку, ця лагідна. Нічого не прочитано, нічого не записано, і ваші дані\nточно такі, якими були. Один запит відхилено.",[57,58],"diagram",{"alt":59,"caption":60,"src":61},"Маршрут зліва направо, від застосунку до високої брами. Брама має порожню пунктирну щілину та бурштиновий засув, стрілка спиняється там, а коротка пунктирна лінія з іншого боку не веде нікуди. Далі праворуч у сірому стоять замок і таблиця всередині пунктирної рамки.","Брама читає ключ. Правила вашої таблиці лежать на крок далі, і відхилений запит до них не доходить.","\u002Fblog\u002Fno-api-key-found-in-request\u002Fwhere-it-stops-1600x620.png",[36,63,65],{"id":64},"чому-мій-запит-прийшов-без-ключа","Чому мій запит прийшов без ключа?",[10,67,68],{},"Бо значення, яке ваш застосунок мав надіслати, не потрапило до запиту, який\nбраузер зробив насправді. Чотири причини покривають майже всі випадки.",[10,70,71,74,75,78,79,84],{},[31,72,73],{},"Ключ так і не дійшов до зібраного застосунку."," Ваш код читає його зі змінної\nсередовища, у збірці, з якої вийшов живий сайт, цієї змінної не було, і\n",[21,76,77],{},"createClient"," отримав порожній рядок. Усе компілюється, застосунок\nзавантажується, і кожен запит іде без ключа. У проєкті на Vite чи Next змінна ще\nй має нести префікс, який позначає її безпечною для браузера, і це\n",[80,81,83],"a",{"href":82},"\u002Fblog\u002Fvite-and-next-public-env-vars","окрема пастка",".",[10,86,87,90,91,94,95,98,99,101],{},[31,88,89],{},"Ви звертаєтеся до REST-шляху вручну."," ",[21,92,93],{},"fetch",", написаний на\n",[21,96,97],{},"\u002Frest\u002Fv1\u002Fваша_таблиця",", надсилає ті заголовки, які ви набрали, і більше нічого.\nКлієнтська бібліотека Supabase додає ",[21,100,48],{}," за вас; запит, написаний руками,\nмає лише те, що ви йому дали.",[10,103,104,107],{},[31,105,106],{},"Щось посередині його прибрало."," Правило перезапису, проксі або ваш власний\nшлюз стоїть між застосунком і Supabase і передає запит без заголовка.",[10,109,110,113,114,117],{},[31,111,112],{},"Ви дивитеся на перенаправлення, а не на запит даних."," Якщо повідомлення\nз'являється після того, як хтось увійшов або натиснув лист підтвердження, а в\nадресному рядку досі ваша адреса Supabase, дивитися треба налаштування Site URL\nу розділі Auth. Відповідь із найбільшою кількістю реакцій у всій тій гілці\nSupabase належить людині, яка записала там адресу свого сайту без ",[21,115,116],{},"https:\u002F\u002F","\nпопереду.",[36,119,121],{"id":120},"виправлення-в-один-рядок","Виправлення, в один рядок",[10,123,124,125,84],{},"Надсилайте свій публічний ключ у заголовку ",[21,126,48],{},[14,128,131],{"className":129,"code":130,"language":19},[17],"import { createClient } from '@supabase\u002Fsupabase-js'\n\nexport const supabase = createClient(\n  'https:\u002F\u002Fваш-проєкт.supabase.co',\n  'sb_publishable_…',\n)\n",[21,132,130],{"__ignoreMap":23},[10,134,135,136,138,139,142],{},"Створіть клієнт отак, і бібліотека покладе ключ у потрібний заголовок у кожному\nзапиті, тож заголовок ви не пишете взагалі. Довідка Supabase точно каже, який це\nзаголовок: публічні та секретні ключі їдуть у ",[21,137,48],{},", а не в\n",[21,140,141],{},"Authorization: Bearer",", бо це короткі непрозорі рядки, і все, що намагається\nперевірити їх як JWT, зазнає невдачі.",[10,144,145,146,150],{},"Цей ключ і має бути у вашому застосунку. Він каже, якому проєкту належить запит,\nа те, до чого відвідувач із ним дістанеться, вирішують правила на ваших\nтаблицях, і саме тому ключ може бути відкритим.\n",[80,147,149],{"href":148},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Які ключі API безпечні у фронтенді","\nпроходить решту родини.",[36,152,154],{"id":153},"виправлення-яке-робить-гірше","Виправлення, яке робить гірше",[10,156,157],{},"Секретний ключ підходить до того самого заголовка, і в старішому проєкті він\nвимкне повідомлення й працюватиме далі.",[10,159,160],{},"Це один невлучний клік. Ваша панель показує обидва ключі на одній сторінці, і\nстара пара схожа: та сама форма, та сама довжина, один під одним. Наскільки\nпоганий цей клік, залежить від того, яку пару видає ваш проєкт.",[10,162,163,166,167,170,171,174],{},[31,164,165],{},"Новіший секретний ключ у браузері відхиляють."," Supabase блокує\n",[21,168,169],{},"sb_secret_…"," за заголовком ",[21,172,173],{},"User-Agent"," і відповідає 401. Тож вставити його у\nфронтенд помилку не прибирає, і це найкращий можливий тут результат.",[10,176,177,184,185,187,188,191],{},[31,178,179,180,183],{},"Старий ключ ",[21,181,182],{},"service_role"," такого блокування не має."," Він працює. Список\nнаповнюється, застосунок поводиться точно як минулого тижня, а ключ тепер лежить\nу файлі, який може завантажити будь-який відвідувач. Там він ігнорує кожне\nправило, яке ви написали: ",[21,186,182],{}," несе атрибут Postgres ",[21,189,190],{},"BYPASSRLS",", тож\nполітика до нього не застосовується ніколи. Кожен рядок у кожній таблиці,\nдоступний на читання й запис тому, хто відкриє той файл.",[10,193,194],{},"Примітку Supabase про блокування в браузері варто прочитати двічі. Блокування\nвідповідає 401, а зловмисник усе одно може скористатися ключем з інших\nінструментів. Захищені тут запити вашого власного застосунку; той самий ключ у\nтому самому файлі відповідає на запит, надісланий зі скрипта.",[57,196],{"alt":197,"caption":198,"src":199},"Один ключ, намальований двічі. Угорі його маршрут із вікна браузера спиняється на суцільному бурштиновому засуві з числом 401. Унизу той самий ключ виходить із термінала й проходить просто крізь місце, де той засув стояв би, намальоване тут пунктирним контуром, аж до трьох рядків таблиці, залитих червоним.","Блокування в браузері стосується браузера. Той самий ключ у тому самому файлі працює з усього, що браузером не є.","\u002Fblog\u002Fno-api-key-found-in-request\u002Fthe-browser-block-1600x640.png",[36,201,203],{"id":202},"інший-хибний-поворот-і-чому-він-такий-легкий","Інший хибний поворот, і чому він такий легкий",[10,205,206],{},"Послабити правило на таблиці теж вимикає повідомлення, і це змінює, хто може\nчитати ваші рядки.",[10,208,209],{},"Ось та гілка Supabase цілком, згрупована за тим, що кожна відповідь пропонує\nзмінити:",[211,212,213,229],"table",{},[214,215,216],"thead",{},[217,218,219,223,226],"tr",{},[220,221,222],"th",{},"Що змінити",[220,224,225],{},"Скільки з восьми відповідей",[220,227,228],{},"Що це змінює насправді",[230,231,232,244,255,265],"tbody",{},[217,233,234,238,241],{},[235,236,237],"td",{},"Site URL у розділі Auth",[235,239,240],{},"1",[235,242,243],{},"Куди веде перенаправлення",[217,245,246,249,252],{},[235,247,248],{},"Політику або grant",[235,250,251],{},"3",[235,253,254],{},"Хто читає й пише ваші рядки",[217,256,257,260,262],{},[235,258,259],{},"Сам запит або сесію",[235,261,251],{},[235,263,264],{},"Ваш власний код",[217,266,267,272,274],{},[235,268,269,270],{},"Заголовок ",[21,271,48],{},[235,273,240],{},[235,275,276],{},"Те, про що просила брама",[10,278,279],{},"Останній рядок це той, що відповідає на підказку в повідомленні. Це найнижчий\nкоментар у гілці, і він має один голос.",[10,281,282],{},"Жодна з решти семи не написана зі злого наміру, і саме це робить справу\nскладною. Одне повідомлення справді з'являється в кількох ситуаціях, людина, яка\nвідповідає, справді повернула свій застосунок до життя, а політика, якої й так\nбракувало, справді потребує лагодження. Збивається порядок: правило переписують,\nщоб вимкнути повідомлення про заголовок, і саме правило та половина цієї пари,\nяку потім ніхто не перевіряє. Ваш застосунок працює в обох випадках, тож ніщо не\nскаже вам, що саме з двох ви зробили.",[10,284,285,286,289],{},"Ззовні результат видно. Наш сканер читає живі застосунки так, як це зробив би\nнезнайомець, і з 31 056 застосунків, яким він виставив оцінку, ",[31,287,288],{},"три","\nопублікували секретний ключ Supabase. Це робить таку знахідку найрідкіснішою з\nусіх, що ми маємо, і найсерйознішою.",[10,291,292,293,296],{},"Сусідній порив куди поширеніший. За 8 435 із тих застосунків ми знайшли проєкт\nSupabase. У 3 680 із них питання «чи може незнайомець прочитати цю таблицю»\nвзагалі дістало придатну відповідь, і ",[31,294,295],{},"2 096 відповіли так",": щонайменше одна\nтаблиця віддала рядки запиту ззовні, у якому не було жодного облікового запису.\nУ 394 з них відкрита таблиця мала назву таблиці з людьми.",[10,298,299,300,84],{},"Частина цього зроблена свідомо. Опубліковане меню, сторінка оголошень і\nпублічний журнал змін живуть у таблицях, які незнайомець і має читати, а наш\nсканер не вміє відрізнити їх від таблиці клієнтів, відкритої через недогляд. Він\nповідомляє, що відповіло, і лишає судження вам, і саме тому\n",[80,301,303],{"href":302},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","увімкнути Row Level Security це не те саме, що бути захищеним",[57,305],{"alt":306,"caption":307,"src":308},"Три смуги на одній шкалі, що коротшають донизу. Перша це всі застосунки, у яких знайдено проєкт Supabase. Друга це менше число, у якому питання про таблицю дістало відповідь, а решта триває пунктирним контуром зі знаком питання. Третя це застосунки, що відповіли ствердно.","Що може прочитати незнайомець, із розрахунку на застосунки, які відповіли. Пунктирна смуга це застосунки, які не відповіли нічого, і це не те саме, що застосунок, у якого нічого не відкрито.","\u002Fblog\u002Fno-api-key-found-in-request\u002Fwhat-answered-1600x620.png",[10,310,311,312,84],{},"Якщо ви радше побачите власну відповідь, ніж виводитимете її, наше безкоштовне\nсканування читає ваш живий сайт і каже, до чого воно дістається ззовні. Воно\nтриває близько 20 секунд і не потребує облікового запису:\n",[80,313,315],{"href":314},"\u002Fsecurity-scanner","просканувати застосунок",[36,317,319],{"id":318},"як-зрозуміти-який-ключ-ви-вставили","Як зрозуміти, який ключ ви вставили",[10,321,322],{},"Прочитайте початок рядка.",[10,324,325,328,329,331],{},[21,326,327],{},"sb_publishable_…"," належить вашому застосунку. ",[21,330,169],{}," ніколи.\nРозкодовувати нічого не треба, бо призначення ключа написане в нього спереду.",[10,333,334,335,338],{},"Довге значення, що починається з ",[21,336,337],{},"eyJ",", належить старішій парі, і саме там ці\nдва стає важко розрізнити. Середня секція такого ключа це читабельна інформація,\nа не шифр, і вона несе поле, яке закриває питання:",[14,340,343],{"className":341,"code":342,"language":19},[17],"{\n  \"iss\": \"supabase\",\n  \"role\": \"anon\",          ← ось що важить\n  \"iat\": 1750000000\n}\n",[21,344,342],{"__ignoreMap":23},[10,346,347,350,351,353,354,356],{},[21,348,349],{},"anon"," це публічний із пари. ",[21,352,182],{}," це той, який варто замінити сьогодні.\nДокументація Supabase каже про це сухіше, ніж сказали б ми: якщо туторіал або\nасистент зі штучним інтелектом радить скопіювати довгий ключ, що починається з\n",[21,355,337],{},", його писали для старих ключів.",[10,358,359,360,362,363,365,366,370,371,375],{},"Обидві пари можуть бути чинними одночасно, і саме на цій деталі спотикаються.\nСтворення публічного або секретного ключа лишає ваші ключі ",[21,361,349],{}," та\n",[21,364,182],{}," рівно там, де вони були, і вони працюють, доки ви не вимкнете їх у\nпанелі окремим кроком.\n",[80,367,369],{"href":368},"\u002Fblog\u002Fsupabase-new-api-keys","Що змінилося з новішими ключами"," розповідає про цей\nперехід, а\n",[80,372,374],{"href":373},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","де у вашій панелі лежить кожне значення","\nце сторінка, яку варто відкрити, якщо ви там ніколи не були.",[36,377,379],{"id":378},"якщо-секретний-ключ-уже-у-вашому-застосунку","Якщо секретний ключ уже у вашому застосунку",[10,381,382],{},"Замініть його, перш ніж щось редагувати, і працюйте в тому порядку, який дає\nSupabase.",[10,384,385,386,388,389,391],{},"Створіть у панелі новий секретний ключ. Замініть старий усюди, де проєкт ним\nкористується. Переконайтеся, що кожна частина застосунку перейшла на новий. І\nлише тоді виводьте старий з ужитку, причому останній крок різниться залежно від\nпари: видалення секретного ключа скасувати неможливо, а вимкнення старої пари\n",[21,387,349],{}," і ",[21,390,182],{}," оборотне, тож ви зможете увімкнути їх назад, якщо\nпропустили якийсь клієнт.",[10,393,394,395,399],{},"Чи міняти ключ першим, чи першим латати витік, залежить від того, чи копія вже\nпублічна.\n",[80,396,398],{"href":397},"\u002Fblog\u002Frotate-supabase-service-role-key","Заміна ключа service_role у Supabase","\nпроходить обидва порядки і каже, що потім читати в журналах.",[36,401,403],{"id":402},"щоб-так-і-лишилося-коли-помилка-зникла","Щоб так і лишилося, коли помилка зникла",[10,405,406,409],{},[31,407,408],{},"Виправлення тримається до наступного промпту чи зміни, що зачіпає ваше\nналаштування Supabase."," Одного промпту досить, щоб ключ знову опинився в\nзастосунку або правило знову послабили, а застосунок працюватиме в обох\nвипадках, тож зміну помітять, лише коли хтось подивиться.",[10,411,412],{},[31,413,414,418],{},[80,415,417],{"href":416},"\u002Fpricing","Reeve Monitor"," дивиться за вас:",[420,421,422,426,429,432],"ul",{},[423,424,425],"li",{},"усі дев'ять перевірок щогодини, для трьох застосунків максимум",[423,427,428],{},"лист того дня, коли повторне сканування оцінить ваш застосунок нижче, ніж попереднє",[423,430,431],{},"чи працює застосунок, кожні 60 секунд",[423,433,434],{},"місячний звіт про те, що він побачив",[10,436,437],{},[31,438,439,440,444],{},"Ключ, який може записати будь-який рядок, може й спорожнити будь-яку таблицю.\n",[80,441,443],{"href":442},"\u002Fsupabase-backups","Reeve Care"," зберігає копію вашої бази Supabase там, куди не\nдотягнеться жоден ключ із вашого застосунку.",[420,446,447,450,453,456,459],{},[423,448,449],{},"зашифрована копія щодня, поза вашим обліковим записом Supabase",[423,451,452],{},"кожна копія перевірена, перш ніж її зарахувати, з підрахунком рядків у кожній таблиці",[423,454,455],{},"відновлення в один клік, яке спершу зберігає поточний стан, а тоді щось замінює",[423,457,458],{},"ваші завантажені файли теж, щойно ви під'єднаєте облікові дані Storage",[423,460,461],{},"усе, що робить Monitor",[36,463,465],{"id":464},"що-зробити-сьогодні","Що зробити сьогодні",[467,468,469],"key-takeaways",{},[420,470,471,474,480,489,492],{},[423,472,473],{},"Читайте повідомлення як відмову на вході. Ваших рядків ніхто не чіпав, і відновлювати нічого не треба.",[423,475,476,477,479],{},"Подивіться у вкладці мережі браузера на невдалий запит і перевірте, чи є там заголовок ",[21,478,48],{}," узагалі. Один цей погляд скаже, це проблема ключа чи перенаправлення.",[423,481,482,483,485,486,488],{},"Створюйте клієнт Supabase із публічним ключем і дайте бібліотеці надсилати заголовок. ",[21,484,327],{}," у новішому проєкті, ключ ",[21,487,349],{}," у старішому.",[423,490,491],{},"Якщо секретний ключ уже у застосунку, спершу замініть його. Видалення з коду дверей не зачиняє, бо стара версія лишається в історії версій і в будь-якій кешованій копії вашого сайту.",[423,493,494],{},"Поверніть на місце кожне правило, яке ви послабили в цих пошуках, і перевіряйте його ззовні, а не з попереднього перегляду свого конструктора.",[10,496,497,498,502,503,507],{},"Почніть із тієї однієї таблиці, з якої прийшла помилка, а далі прочитайте\nполітики кожної таблиці, якої торкалися того самого тижня.\n",[80,499,501],{"href":500},"\u002Fchecklist","Чекліст безпеки на 10 хвилин"," покриває, що ще зазвичай лишається\nвідкритим у щойно запущеному застосунку, а\n",[80,504,506],{"href":505},"\u002Fis-your-supabase-app-safe","посібник з безпеки Supabase"," проходить решту того, до\nчого може дістатися незнайомець.",{"title":23,"searchDepth":509,"depth":509,"links":510},3,[511,513,514,515,516,517,518,519,520],{"id":38,"depth":512,"text":39},2,{"id":64,"depth":512,"text":65},{"id":120,"depth":512,"text":121},{"id":153,"depth":512,"text":154},{"id":202,"depth":512,"text":203},{"id":318,"depth":512,"text":319},{"id":378,"depth":512,"text":379},{"id":402,"depth":512,"text":403},{"id":464,"depth":512,"text":465},"Основи безпеки","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcover-1200x630.png","Запит приходить до високої брами з порожньою щілиною для перепустки і засувом упоперек, а база даних, до якої він ішов, лишається позаду недоторканою.","\"No API key found in request\" означає, що запит дійшов до Supabase без ключа. Більшість відповідей натомість вказують на правила вашої бази.",false,"md",[528,531,534,537,540],{"q":529,"a":530},"Що означає \"No API key found in request\"?","Це означає, що ваш запит дійшов до Supabase без заголовка apikey, тож брама, яку Supabase ставить перед вашим проєктом, розвернула його ще до того, як база даних узяла участь. Нічого не прочитано, нічого не записано, і у ваших даних нічого не змінилося. Відповідь несе підказку, яка каже те саме іншими словами: no apikey request header or url param was found.",{"q":532,"a":533},"Який ключ Supabase іде в заголовок apikey?","Ваш публічний ключ, тобто sb_publishable_ у новішому проєкті та ключ anon у старішому. Supabase видає його саме для цього й очікує, що він буде видимим усередині вашого застосунку. Клієнтська бібліотека ставить його в заголовок у кожному запиті, тож якщо ви створюєте клієнт із публічним ключем, заголовок вручну не пишете ніколи.",{"q":535,"a":536},"Чи безпечно тримати ключ anon у браузері?","Так, і він має там бути, щоб ваш застосунок узагалі міг говорити з вашим проєктом. Ключ anon лише каже, якому проєкту належить запит; те, до чого відвідувач із ним реально дістанеться, вирішують правила Row Level Security на ваших таблицях. Які ключі API безпечні у фронтенді проходить усю родину ключів і показує, як їх читати.",{"q":538,"a":539},"Я скористався ключем service_role, і воно запрацювало. Це проблема?","Так, і саме це варто владнати сьогодні. Ключ service_role несе атрибут Postgres BYPASSRLS, тож ваші політики до нього не застосовуються ніколи. Опублікований усередині застосунку, він лежить у файлі, який може завантажити будь-який відвідувач, і той, хто завантажить, зможе читати й писати кожен рядок у кожній таблиці. Спершу змініть ключ, а потім перенесіть на сервер те, що його потребувало.",{"q":541,"a":542},"Як дізнатися, який ключ я вставив?","Прочитайте початок рядка. sb_publishable_ належить вашому застосунку, а sb_secret_ ніколи. Довге значення, що починається з eyJ, належить старішій парі, а ці два виглядають однаково, тож треба зазирнути всередину: середня секція розкодовується у читабельні дані з полем role, де стоїть або anon, або service_role.","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",[545,546,547,548,549,550,551],"no api key found in request","no api key found in request supabase","supabase не знайдено api key","supabase бракує заголовка apikey","401 недійсний api key supabase","supabase api key не працює","supabase 401 unauthorized",{},true,"\"No API key found in request\" у Supabase","\u002Fblog\u002Fno-api-key-found-in-request","2026-10-07",{"title":5,"description":524},"blog\u002Fno-api-key-found-in-request",[560,561,562],"\"No API key found in request\" означає, що ваш запит дійшов до Supabase без заголовка apikey, тож його розвернули на вході ще до того, як щось запитали у вашої бази даних.","Правильне виправлення це ваш публічний ключ у тому самому заголовку, тобто ключ, який і має бути відкритим. Клієнтська бібліотека Supabase надсилає його за вас у кожному запиті.","Два виправлення, до яких беруться натомість, це секретний ключ і послаблене правило на таблиці. Обидва вимикають повідомлення, і обидва лишають ваші рядки доступними кожному, хто має ключ, що їде всередині вашого застосунку.","xIxFsR-WLPgemSLu2FYnTGVUnuV7nNrmV6auWrmfyug",[565,571,577,583,589,590,596,602,608,614,620,626,632,638,645,651,657,662,668,674,680,686,692,698,704,709,715,721,727,733,739,745,751,757,763,768,774,780,786,792,798,804,810,816,822,828,833,839,845,851,857,863,869,875,881,886,891,897,902,907,913],{"path":566,"title":567,"description":568,"published":569,"category":521,"image":570,"draft":525},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" при вивантаженні","\"New row violates row-level security policy for table objects\" означає, що вашому вивантаженню бракує правила insert. Публічний бакет його не додає.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":572,"title":573,"description":574,"published":575,"category":521,"image":576,"draft":525},"\u002Fblog\u002Fbase44-security-scan","Сканування безпеки Base44: те, що бачить лише воно","Сканування безпеки Base44 перевіряє сім видів проблем зсередини. Ось половина, яку читає тільки воно, і половина, на яку воно ніколи не дивиться.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":578,"title":579,"description":580,"published":581,"category":521,"image":582,"draft":525},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Ваш API-ключ витік. Порядок дій","API-ключ витік, і ви не знаєте, що робити першим. Не кожен ключ у вашому фронтенді є витоком, а порядок важить більше за швидкість.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":584,"title":585,"description":586,"published":587,"category":521,"image":588,"draft":525},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" без вимкнення RLS","\"Infinite recursion detected in policy for relation\" означає, що ваша policy запитала таблицю, яку вона захищає. Ось як розірвати коло.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":555,"title":5,"description":524,"published":556,"category":521,"image":543,"draft":525},{"path":591,"title":592,"description":593,"published":594,"category":521,"image":595,"draft":525},"\u002Fblog\u002Fis-base44-safe","Чи безпечний Base44? Дані 5 442 застосунків","Чи безпечний Base44? Ми прогнали дев’ять перевірок на 5 442 робочих застосунках Base44. Майже всі отримали B з причин, яких власник ніколи не обирав.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":597,"title":598,"description":599,"published":600,"category":521,"image":601,"draft":525},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Сховати ключ API: перенесіть його в Supabase Edge Function","Сховати ключ API означає прибрати його з браузера, а Supabase Edge Function це найменше місце, куди його покласти. Два кроки поруч важать більше.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":603,"title":604,"description":605,"published":606,"category":521,"image":607,"draft":525},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Чи відкритий ваш файл .env? Дванадцять шляхів для перевірки","Чи відкритий ваш файл .env на вашому власному вебсервері? Дванадцять адрес скажуть це за хвилину, а влучання означає, що все в ньому вже публічне.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":609,"title":610,"description":611,"published":612,"category":521,"image":613,"draft":525},"\u002Fblog\u002Fis-v0-safe","Безпека v0: усі 1 790 просканованих застосунків v0 отримали A","Безпека v0 на 1 790 живих застосунках v0: усі отримали A. Лише 17 згадували базу даних, і саме це здебільшого вимірює оцінка A.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":615,"title":616,"description":617,"published":618,"category":521,"image":619,"draft":525},"\u002Fblog\u002Fis-bolt-safe","Чи безпечний Bolt? Що показали 1 123 застосунки Bolt","Чи безпечний Bolt? Ми прогнали 1 123 живі застосунки Bolt через дев’ять перевірок. Хостинг був чистим. Знахідки: ключі й відкриті таблиці в самих застосунках.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":621,"title":622,"description":623,"published":624,"category":521,"image":625,"draft":525},"\u002Fblog\u002Fis-supabase-down-or-your-app","Supabase не працює чи проблема у вашому застосунку? Як розрізнити","Supabase не працює чи зламався ваш застосунок? Пауза, повна база й ваша власна помилка виглядають однаково. Чотири перевірки їх розрізняють.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":627,"title":628,"description":629,"published":630,"category":521,"image":631,"draft":525},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Чи шифрує Supabase мої дані? Так. Ось від чого це захищає","Чи шифрує Supabase дані? Так: AES-256 у стані спокою, TLS під час передавання, SOC 2 та ISO 27001. Що покриває кожне і який витік не зупиняє жодне.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":633,"title":634,"description":635,"published":636,"category":521,"image":637,"draft":525},"\u002Fblog\u002Fsupabase-free-plan-limits","Ліміти безкоштовного тарифу Supabase і що стається на кожному","Ліміти безкоштовного тарифу Supabase: 500 МБ бази, 5 ГБ egress і жодних резервних копій. Що стається на кожній межі і що змінює Pro за $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":639,"title":640,"description":641,"published":642,"category":643,"image":644,"draft":525},"\u002Fblog\u002Ftest-your-supabase-backup","Перевірте резервну копію Supabase до того, як вона знадобиться","Як перевірити резервну копію Supabase: відновити в тестовий проєкт, порахувати рядки, увійти й знайти рядок, якого бракує обрізаному файлу.","2026-09-28","Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":646,"title":647,"description":648,"published":649,"category":643,"image":650,"draft":525},"\u002Fblog\u002Fsupabase-backup-github-action","Безкоштовна резервна копія Supabase через GitHub Action і підступ","Резервна копія Supabase через GitHub Action безкоштовна й годиться багатьом застосункам. Робочий процес, потрібний рядок підключення та egress.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":652,"title":653,"description":654,"published":655,"category":643,"image":656,"draft":525},"\u002Fblog\u002Fdownload-your-supabase-backup","Чому ви не можете завантажити резервну копію Supabase","Завантажити резервну копію Supabase на сучасному проєкті не вийде: щоденна копія там фізична. Як це перевірити і як тримати власну копію.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":658,"title":659,"description":660,"published":655,"category":521,"image":661,"draft":525},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": бракує GRANT","З 30 жовтня нова таблиця в Supabase відповідає \"permission denied for table\", доки ви не дасте доступ. Лист показує лише половину виправлення.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":663,"title":664,"description":665,"published":666,"category":521,"image":667,"draft":525},"\u002Fblog\u002Fopen-api-endpoint-exposed","Чи є відкритий API-ендпоінт проблемою безпеки? Читайте JSON","Ваше сканування позначило відкритий API-ендпоінт. Чи це важливо, залежить від того, що повернулося, і більшість знайдених належали платформі.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":669,"title":670,"description":671,"published":672,"category":521,"image":673,"draft":525},"\u002Fblog\u002Flovable-security-scan","Сканування безпеки Lovable: чого воно не доведе","Сканування безпеки Lovable: що перевіряють Quick scan і Deep scan, коли запускається кожне, і єдине, чого не доведе жодне сканування зсередини.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":675,"title":676,"description":677,"published":678,"category":643,"image":679,"draft":525},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":681,"title":682,"description":683,"published":684,"category":521,"image":685,"draft":525},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":687,"title":688,"description":689,"published":690,"category":521,"image":691,"draft":525},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":693,"title":694,"description":695,"published":696,"category":521,"image":697,"draft":525},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":699,"title":700,"description":701,"published":702,"category":521,"image":703,"draft":525},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":82,"title":705,"description":706,"published":707,"category":521,"image":708,"draft":525},"Змінні оточення Vite відкриті: префікс означає опублікувати це","Змінні оточення Vite відкриті у вашому застосунку, бо так просив префікс. VITE_ і NEXT_PUBLIC_ означають опублікувати це, а ШІ, який їх додав, не знав ціни.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":710,"title":711,"description":712,"published":713,"category":521,"image":714,"draft":525},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":716,"title":717,"description":718,"published":719,"category":521,"image":720,"draft":525},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":722,"title":723,"description":724,"published":725,"category":521,"image":726,"draft":525},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":728,"title":729,"description":730,"published":731,"category":643,"image":732,"draft":525},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":734,"title":735,"description":736,"published":737,"category":643,"image":738,"draft":525},"\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":740,"title":741,"description":742,"published":743,"category":643,"image":744,"draft":525},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":746,"title":747,"description":748,"published":749,"category":521,"image":750,"draft":525},"\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":752,"title":753,"description":754,"published":755,"category":521,"image":756,"draft":525},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Увімкніть Row Level Security на кожній таблиці Supabase і перевірте","Row Level Security у Supabase без політики закриває таблицю повністю. Політика без увімкненого перемикача не робить нічого. Ось SQL, і ось перевірка.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":758,"title":759,"description":760,"published":761,"category":521,"image":762,"draft":525},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": чого не бачить попередження","Supabase позначає \"RLS disabled in public\" як помилку. Про політику читання, яка лишає вашу таблицю так само відкритою, він не каже нічого.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":397,"title":764,"description":765,"published":766,"category":521,"image":767,"draft":525},"Як замінити злитий ключ service_role у Supabase","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":769,"title":770,"description":771,"published":772,"category":521,"image":773,"draft":525},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Десять інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":775,"title":776,"description":777,"published":778,"category":521,"image":779,"draft":525},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":781,"title":782,"description":783,"published":784,"category":521,"image":785,"draft":525},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":787,"title":788,"description":789,"published":790,"category":521,"image":791,"draft":525},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":793,"title":794,"description":795,"published":796,"category":521,"image":797,"draft":525},"\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":799,"title":800,"description":801,"published":802,"category":521,"image":803,"draft":525},"\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":805,"title":806,"description":807,"published":808,"category":643,"image":809,"draft":525},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":811,"title":812,"description":813,"published":814,"category":521,"image":815,"draft":525},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":817,"title":818,"description":819,"published":820,"category":643,"image":821,"draft":525},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":823,"title":824,"description":825,"published":826,"category":521,"image":827,"draft":525},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":373,"title":829,"description":830,"published":831,"category":521,"image":832,"draft":525},"Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":834,"title":835,"description":836,"published":837,"category":521,"image":838,"draft":525},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","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":840,"title":841,"description":842,"published":843,"category":521,"image":844,"draft":525},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":846,"title":847,"description":848,"published":849,"category":643,"image":850,"draft":525},"\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":852,"title":853,"description":854,"published":855,"category":643,"image":856,"draft":525},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":858,"title":859,"description":860,"published":861,"category":521,"image":862,"draft":525},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":864,"title":865,"description":866,"published":867,"category":521,"image":868,"draft":525},"\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":870,"title":871,"description":872,"published":873,"category":643,"image":874,"draft":525},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":876,"title":877,"description":878,"published":879,"category":521,"image":880,"draft":525},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Чи може будь-хто прочитати вашу базу Supabase? 3 680 застосунків","Чи може будь-хто прочитати вашу базу даних Supabase без входу? Ми просканували 30 998 живих застосунків, зроблених ШІ-білдерами, і виміряли, як часто так.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":882,"title":883,"description":884,"published":879,"category":521,"image":885,"draft":525},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":368,"title":887,"description":888,"published":889,"category":521,"image":890,"draft":525},"Нові API-ключі Supabase: який із них безпечний у застосунку?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":892,"title":893,"description":894,"published":895,"category":643,"image":896,"draft":525},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":302,"title":898,"description":899,"published":900,"category":521,"image":901,"draft":525},"Supabase Row Level Security увімкнено. Таблиця досі публічна.","Увімкнути Supabase Row Level Security не означає захистити таблицю. Захищають політики, а та, що полагодила застосунок, часто впускає всіх.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":903,"title":904,"description":905,"published":900,"category":643,"image":906,"draft":525},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":908,"title":909,"description":910,"published":911,"category":643,"image":912,"draft":525},"\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":148,"title":914,"description":915,"published":911,"category":521,"image":916,"draft":525},"Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1791705965535]