[{"data":1,"prerenderedAt":664},["ShallowReactive",2],{"blog-uk-rotate-supabase-service-role-key":3,"blog-index-uk":423},{"id":4,"title":5,"body":6,"category":380,"cover":381,"coverAlt":382,"description":383,"draft":384,"extension":385,"faq":386,"image":401,"keywords":402,"meta":411,"navigation":412,"ogTitle":413,"path":414,"published":415,"seo":416,"stem":417,"tldr":418,"updated":415,"__hash__":422},"blog_uk\u002Fblog\u002Frotate-supabase-service-role-key.md","Як замінити злитий ключ service_role у Supabase",{"type":7,"value":8,"toc":365},"minimark",[9,24,27,30,33,41,52,55,70,81,85,88,95,101,104,110,114,120,123,148,151,154,161,170,176,206,218,223,231,241,245,248,265,275,281,285,288,291,294,304,308,311,314,320,324,355],[10,11,12,13,17,18,23],"p",{},"Вам сказали, що ваш ключ ",[14,15,16],"code",{},"service_role"," у Supabase лежить у застосунку, де його\nможе прочитати будь-хто. Перш ніж щось міняти, переконайтеся, що знайшли саме\nцей ключ: ",[19,20,22],"a",{"href":21},"\u002F#scan","наше безкоштовне сканування"," читає ваш живий сайт так само,\nяк прочитав би сторонній, і каже, який ключ Supabase воно там справді бачить.\nБез облікового запису й без встановлення чогось.",[10,25,26],{},"Порада, що йде за такою знахідкою, майже завжди складається з одного слова:\nміняйте. Далі ви шукаєте, як це зробити, і джерела суперечать одне одному.\nВласна документація Supabase починає свій посібник із ротації словами, що\nспершу треба усунути причину витоку. Пів десятка сторонніх посібників радять\nміняти негайно, а питання ставити потім.",[10,28,29],{},"Ось частина, якої не пише жоден із них: обидва мають рацію, але в різних\nситуаціях, і питання, яке їх розділяє, це куди саме потрапив ключ.",[10,31,32],{},"Одне варто прояснити наперед. Видалити ключ із коду означає зняти власну копію\nзі зв'язки. Замінити його означає змінити замок. Лише друге дістає до копій, які\nвже є в інших.",[34,35,37,38,40],"h2",{"id":36},"це-справді-ключ-service_role","Це справді ключ ",[14,39,16],{},"?",[10,42,43,44,47,48,51],{},"У новішому проєкті відповідь дають перші кілька символів. ",[14,45,46],{},"sb_secret_"," на\nпочатку означає секретний. ",[14,49,50],{},"sb_publishable_"," це ключ, який і має бути у вашому\nзастосунку, і знайти його там взагалі не знахідка.",[10,53,54],{},"Переконайтеся до того, як робити щось різке, бо ключ, який знаходять у\nзастосунку, зібраному в стилі vibe coding, зазвичай і є тим, якому там місце.",[10,56,57,58,61,62,64,65,69],{},"Старіші проєкти видають іншу пару, ",[14,59,60],{},"anon"," і ",[14,63,16],{},", і ці два виглядають\nмайже однаково: той самий формат, та сама довжина, жодного префікса для\nчитання. Середня секція такого ключа взагалі не зашифрована. Вона розкодовується\nв кілька рядків звичайного тексту, і один із них називає роль.\n",[19,66,68],{"href":67},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Які ключі API безпечні у фронтенді","\nпроходить обидві перевірки.",[10,71,72,73,75,76,80],{},"Причина переконатися в тому, що це трапляється рідше, ніж підказують\nпопередження. У серпні 2026 року ми просканували 30 998 живих застосунків,\nзібраних у стилі vibe coding, і знайшли опублікований ключ ",[14,74,16],{}," у 3 з\nних. Ключ API Google, який зазвичай нешкідливий і часто обмежений одним доменом,\nтрапився в 1 142.\n",[19,77,79],{"href":78},"\u002Fresearch\u002Fvibe-coded-app-security-2026","Повний підрахунок тут",".",[34,82,84],{"id":83},"спершу-замінити-чи-спершу-закрити-витік","Спершу замінити чи спершу закрити витік?",[10,86,87],{},"Це залежить від того, чи ключ уже публічний, і межа між двома випадками чітка.",[10,89,90,94],{},[91,92,93],"strong",{},"Якщо ключ лежить у JavaScript, який завантажують ваші відвідувачі, він уже\nпублічний."," Копія є в кожного, хто відкрив ваш сайт, поки ключ був живий, і в\nкожного автоматичного сканера, який шукав саме цей рядок. Ніщо зі змін у вашому\nкоді до тих копій не дістане. Спершу замініть, потім закрийте джерело.",[10,96,97,100],{},[91,98,99],{},"Якщо він потрапив лише в приватний репозиторій, файл логу, змінну CI чи чат,\nрозголос обмежений."," Замінивши тут першою чергою, ви зробите це двічі, бо\nнаступний деплой знову виштовхне старе значення з того, що його породжує, і\nновий ключ піде слідом за старим. Спершу закрийте джерело, потім замінюйте.",[10,102,103],{},"Посібник Supabase написаний для другого випадку. Термінові посібники написані\nдля першого. Якщо ви читаєте це тому, що сканер знайшов ключ на вашій живій\nURL-адресі, ви в першому випадку.",[105,106],"diagram",{"alt":107,"caption":108,"src":109},"Дві доріжки. Верхня починається з вікна браузера й проходить крок один, ключ зі стрілкою обертання, потім крок два, пару кутових дужок. Нижня починається з файлу й проходить ті самі два кроки у зворотному порядку, спершу дужки, потім ключ.","Ті самі два завдання, зворотний порядок. Вирішує те, чи злита копія вже гуляє світом.","\u002Fblog\u002Frotate-supabase-service-role-key\u002Ftwo-orders-1600x640.png",[34,111,113],{"id":112},"як-замінити-секретний-ключ-supabase","Як замінити секретний ключ Supabase",[10,115,116,117,119],{},"Якщо у вашому проєкті є ключі ",[14,118,46],{},", це робота в панелі й без простою.",[10,121,122],{},"Проєкт може тримати кілька секретних ключів одночасно, кожен зі своєю назвою, і\nсаме це робить операцію безпечною: ви додаєте новий до того, як прибрати старий,\nтож між цими двома моментами ніщо не зламане.",[124,125,126,134,142,145],"ol",{},[127,128,129,130,133],"li",{},"Відкрийте проєкт, перейдіть у ",[91,131,132],{},"Settings → API Keys"," і створіть новий\nсекретний ключ.",[127,135,136,137,141],{},"Пропишіть його скрізь, де використовувався старий, а це все має бути на\nсервері: edge-функції, вебхуки, заплановані завдання, власний бекенд.\n",[19,138,140],{"href":139},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Де лежать ці значення",", якщо ви\nніколи не відкривали ту сторінку.",[127,143,144],{},"Зробіть деплой, потім пройдіться частинами застосунку, які читають і пишуть\nдані. Неправильний секретний ключ падає гучно й одразу, і це добрий випадок.",[127,146,147],{},"Тільки після цього видаліть скомпрометований ключ.",[10,149,150],{},"Крок 4 остаточний. Supabase справді видаляє секретний ключ: без скасування, без\nповторного ввімкнення, без відкладеної копії, яку можна повернути. Тому він і\nйде останнім.",[10,152,153],{},"Видалення секретного ключа не виводить ваших користувачів із сеансів. Ключ API\nкаже, який застосунок звертається до вашої бази даних, а токен сеансу\nвідвідувача каже, який це користувач. Друге перевіряється за ключем підпису\nвашого проєкту, а це окреме значення, якого ви не чіпали.",[34,155,157,158,160],{"id":156},"чому-старий-ключ-service_role-у-supabase-не-можна-замінити","Чому старий ключ ",[14,159,16],{}," у Supabase не можна замінити",[10,162,163,164,166,167,169],{},"Бо для цього немає кнопки. Нотатка Supabase з усунення несправностей каже, що\nпряма ротація старих секретів ",[14,165,60],{},", ",[14,168,16],{}," і JWT більше не\nпідтримується, і скеровує вас до нових ключів.",[10,171,172,173,175],{},"Тож знецінити злитий старий ключ ",[14,174,16],{}," це міграція, а не ротація:",[124,177,178,189,195,200],{},[127,179,180,183,184,61,186,188],{},[91,181,182],{},"Створіть нові ключі."," Це додає ",[14,185,50],{},[14,187,46],{}," поруч зі\nстарою парою. Обидві системи працюють одночасно, і ніщо не ламається.",[127,190,191,194],{},[91,192,193],{},"Переведіть фронтенд на публічний ключ."," У Lovable чи Bolt це зазвичай одне\nзначення в налаштуваннях проєкту, а не рядок коду.",[127,196,197],{},[91,198,199],{},"Переведіть кожне серверне використання на секретний ключ.",[127,201,202,205],{},[91,203,204],{},"Вимкніть старі ключі"," в налаштуваннях проєкту.",[10,207,208,209,211,212,214,215,217],{},"Крок 4 це один перемикач, і він стосується обох старих ключів. ",[14,210,60],{}," і\n",[14,213,16],{}," є JWT, підписаними тим самим секретом, тож перемикач, що\nвідкликає один, відкликає й другий, а фронтенд, який досі несе старий ключ\n",[14,216,60],{},", перестає працювати тієї миті, коли ви його натискаєте. Саме тому крок 2\nйде раніше.",[105,219],{"alt":220,"caption":221,"src":222},"Панель налаштувань із чотирма рядками. Два верхні, sb_publishable_ і sb_secret_, мають заповнену крапку й значення, яке можна прочитати. Під роздільником anon і service_role намальовані приглушено, їхні значення замасковані крапками, а фігурна дужка сполучає обидва ці рядки з одним перемикачем у вимкненому положенні.","Вимкнення старих ключів це один елемент керування для обох. Ключ anon, яким користується ваш застосунок, іде разом із ключем service_role, який ви хочете знецінити.","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fone-switch-two-keys-1600x720.png",[10,224,225,226,230],{},"Вимкнення оборотне, і це єдина добра новина в цьому розділі: якщо щось забуте\nдосі користується старим ключем, ви вмикаєте їх назад, поки це виправляєте.\n",[19,227,229],{"href":228},"\u002Fblog\u002Fsupabase-new-api-keys","Що входить у міграцію"," розказано там докладніше.",[232,233,235],"callout",{"type":234},"warn",[10,236,237,240],{},[91,238,239],{},"До кроку 4 злитий ключ і далі працює."," Кроки з 1 по 3 додають другий шлях\nусередину; вони нічого не забирають. У проєкті, де ключ уже публічний, саме це\nробить такий порядок незручним, і саме тому чотири кроки варто робити один за\nодним. Недороблена міграція лишає старий ключ живим, а ваш застосунок працює\nвідразу на двох системах ключів.",[34,242,244],{"id":243},"звідки-витік-ключ-і-як-це-закрити","Звідки витік ключ і як це закрити",[10,246,247],{},"Три причини пояснюють майже все, і всі три лежать усередині вашого власного\nпроєкту.",[10,249,250,260,261,264],{},[91,251,252,253,256,257,80],{},"Префікс ",[14,254,255],{},"VITE_"," або ",[14,258,259],{},"NEXT_PUBLIC_"," Це не налаштування безпеки, яке хтось\nзабув увімкнути. Це вказівка збірці: поклади це значення в бандл. Змінна з\nназвою ",[14,262,263],{},"VITE_SUPABASE_SERVICE_ROLE_KEY"," потрапила у ваш JavaScript навмисно,\nчерез інструмент, який зробив рівно те, що йому сказали.",[10,266,267,270,271,274],{},[91,268,269],{},"Значення, вставлене просто в компонент."," Жодного префікса й жодного файлу\n",[14,272,273],{},".env",", лише ключ у рядку коду, бо це був найшвидший спосіб змусити запит щось\nповернути.",[10,276,277,280],{},[91,278,279],{},"Робота, місце якої на сервері."," Видалити обліковий запис, записати в таблицю,\nкуди вашим користувачам писати не можна, прочитати рядки по всіх одразу. За ключ\nузялися, бо браузер не міг виконати цю роботу, і рішення в тому, щоб перенести\nсаму роботу: edge-функція, serverless-маршрут, будь-що, чого ваші відвідувачі не\nзавантажують.",[34,282,284],{"id":283},"як-дізнатися-чи-хтось-ним-скористався","Як дізнатися, чи хтось ним скористався?",[10,286,287],{},"Зазвичай напевно дізнатися не вийде. Що ви можете, так це звузити вікно й\nзазирнути всередину.",[10,289,290],{},"Вікно відкривається деплоєм, який уперше опублікував ключ, і закривається тоді,\nколи ви його вимкнули. Ваш проєкт Supabase веде логи і для API, і для бази\nданих, і саме за цим діапазоном їх треба фільтрувати. Ви шукаєте читання й\nзаписи, яких не можете пояснити: запити до таблиць, яких ваш застосунок ніколи\nне торкається, трафік у години, коли ним ніхто не користувався, видалення, яких\nніхто не робив.",[10,292,293],{},"Далі перевірте самі дані. Кількість рядків проти того, що ви очікуєте, ваші\nвласні записи облікового запису, будь-що з міткою часу, яка зрушила, поки ніхто\nне працював. Повідомлення в підтримку про дані, що змінилися самі собою, це\nспосіб, у який більшість таких випадків справді виявляють, і воно приходить за\nкілька тижнів.",[10,295,296,297,299,300,80],{},"Ключ ",[14,298,16],{}," не дістає ні до вашого платіжного провайдера, ні до\nрозсилання пошти. Усе одно варто знати, чи був він єдиним ключем у вашому\nбандлі, бо ті, що витрачають гроші, витікають тим самим шляхом:\n",[19,301,303],{"href":302},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","що публікували 30 998 застосунків",[34,305,307],{"id":306},"перевірте-живий-застосунок-перш-ніж-вважати-справу-закритою","Перевірте живий застосунок, перш ніж вважати справу закритою",[10,309,310],{},"Завантажте сайт у приватному вікні, відкрийте JavaScript, який завантажив\nбраузер, і пошукайте в ньому старе значення. Потім пошукайте нове, якого там\nтеж бути не повинно.",[10,312,313],{},"Дві речі роблять цю ручну перевірку доречною. Збірка може ще якийсь час після\nдеплою віддавати закешований бандл, тож файл, який отримує відвідувач, не завжди\nтой, що ви щойно зібрали. І ключ може лежати не в одному місці: друга точка\nвходу, service worker, стара збірка, яку досі віддають зі шляху, на який ніхто\nне посилається.",[10,315,316,317,80],{},"Наше безкоштовне сканування робить цю частину ззовні, за URL-адресою, якою\nсправді користуються ваші відвідувачі, і розкодовує ключ Supabase достатньо\nглибоко, щоб прочитати роль, тож публічний ключ повертається з галочкою. Це\nзаймає близько двадцяти секунд і не потребує облікового запису:\n",[19,318,319],{"href":21},"просканувати застосунок",[34,321,323],{"id":322},"що-робити-зараз","Що робити зараз",[325,326,327],"key-takeaways",{},[328,329,330,340,343,346,349,352],"ul",{},[127,331,332,333,335,336,339],{},"Спершу підтвердьте ключ. ",[14,334,46],{}," спереду або ",[14,337,338],{},"\"role\": \"service_role\""," усередині старішого. Публічний ключ у вашому фронтенді це не знахідка.",[127,341,342],{},"Якщо він у бандлі, який завантажують ваші відвідувачі, замініть його до того, як міняти код. Правки в застосунку не дістають до копій, які вже пішли назовні.",[127,344,345],{},"Якщо він витік лише в репозиторій, лог чи чат, спершу закрийте джерело, щоб наступний деплой не виштовхнув новий ключ назовні слідом.",[127,347,348],{},"У новішому проєкті: створіть другий секретний ключ, переведіть на нього код сервера, зробіть деплой, потім видаліть старий. Видалення остаточне.",[127,350,351],{},"У старому проєкті кнопки заміни немає. Створіть нові ключі, переведіть на них фронтенд і сервер, а тоді вимкніть стару пару тим єдиним перемикачем, що стосується обох.",[127,353,354],{},"Після цього пошукайте у своєму живому бандлі. Закешована збірка може віддавати старе значення ще якийсь час після деплою.",[10,356,296,357,359,360,364],{},[14,358,16],{}," читає й пише кожен рядок вашої бази даних. Найгірша версія\nцієї історії закінчується порожньою таблицею, і чи повернуться ті рядки,\nзалежить від того,\n",[19,361,363],{"href":362},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","що саме ви зберігали",", перш\nніж усе це сталося.",{"title":366,"searchDepth":367,"depth":367,"links":368},"",3,[369,372,373,374,376,377,378,379],{"id":36,"depth":370,"text":371},2,"Це справді ключ service_role?",{"id":83,"depth":370,"text":84},{"id":112,"depth":370,"text":113},{"id":156,"depth":370,"text":375},"Чому старий ключ service_role у Supabase не можна замінити",{"id":243,"depth":370,"text":244},{"id":283,"depth":370,"text":284},{"id":306,"depth":370,"text":307},{"id":322,"depth":370,"text":323},"Основи безпеки","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcover-1200x630.png","Навісний замок, а поруч два однакові ключі того самого розміру, один світлий, другий приглушений.","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.",false,"md",[387,390,393,396,398],{"q":388,"a":389},"Чи зламає заміна ключа мій застосунок, який уже працює?","Ні, якщо дотримати порядку. У проєкті з новими ключами ви додаєте другий секретний ключ, переводите на нього код сервера, робите деплой і лише тоді видаляєте старий, тож не буває моменту без робочого ключа. У старому проєкті ризик інший: вимкнення старої пари вимикає й ключ anon, який використовує ваш фронтенд, тож застосунок упаде, якщо він на момент перемикання ще не перейшов на публічний ключ.",{"q":391,"a":392},"Чи можна ротувати старі ключі anon і service_role?","Ні. Документація Supabase з усунення несправностей каже, що пряма ротація старих секретів anon, service_role і JWT більше не підтримується. Щоб знецінити злитий старий ключ, треба створити нові ключі sb_publishable_ і sb_secret_, перевести на них застосунок і код сервера, а потім вимкнути стару пару в налаштуваннях проєкту.",{"q":394,"a":395},"Видалити старий ключ чи вимкнути його?","Вибору немає, бо дві системи ключів поводяться по-різному. Новіший ключ sb_secret_ саме видаляється, назавжди, без жодного способу повернути. Стару пару натомість вимикають, і вимкнення оборотне: якщо щось забуте досі користується старим ключем, ви вмикаєте їх назад, поки це виправляєте.",{"q":284,"a":397},"Зазвичай напевно дізнатися не вийде. Натомість звузьте це до вікна: ключ був придатний від деплою, який уперше його опублікував, до моменту, коли ви його вимкнули. Відфільтруйте логи API та бази даних вашого проєкту Supabase за цим діапазоном і шукайте читання й записи, яких не можете пояснити, а потім перевірте самі дані: кількість рядків і мітки часу, що не збігаються ні з чим, що ви робили.",{"q":399,"a":400},"Чи треба замінювати й ключ anon?","У старому проєкті вибору немає: вимкнення старої пари забирає обидва ключі одразу, тож ваш фронтенд має отримати новий публічний ключ до того, як ви натиснете перемикач. У новішому проєкті публічний ключ і задуманий як публічний, і чіпати його немає причин. Що варто перевірити в обох випадках, так це Row Level Security, бо це єдине, що стоїть між публічним ключем і всією вашою базою даних.","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",[403,404,405,406,407,408,409,410],"замінити ключ service role supabase","як ротувати service role key у supabase","ключ service role supabase злитий","ключ service role supabase у відкритому доступі","ротація ключів supabase","відкликати api-ключ supabase","вимкнути старі api-ключі supabase","service role key у фронтенді",{},true,"Замінити злитий ключ service_role у правильному порядку","\u002Fblog\u002Frotate-supabase-service-role-key","2026-09-08",{"title":5,"description":383},"blog\u002Frotate-supabase-service-role-key",[419,420,421],"Якщо ваш ключ service_role у Supabase лежить у JavaScript, який завантажує браузер, замініть його перш ніж щось лагодити. Копія, яка вже пішла назовні, не має терміну придатності.","Якщо він потрапив лише в приватний репозиторій чи лог, спершу закрийте джерело, інакше новий ключ вийде назовні слідом за старим на наступному деплої.","Старий ключ service_role замінити взагалі неможливо. Щоб знецінити його, треба створити нові ключі sb_secret_, перевести застосунок на них і вимкнути стару пару перемикачем, який стосується обох.","qQZvorgr-ddGb8i6Fevsl4OTEbQ0-eMaGuiu7avpkm0",[424,431,437,443,449,455,461,467,473,479,485,491,497,503,509,515,516,522,528,534,540,546,551,557,563,569,575,580,586,592,598,604,610,616,622,628,633,638,644,650,655,660],{"path":425,"title":426,"description":427,"published":428,"category":429,"image":430,"draft":384},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":432,"title":433,"description":434,"published":435,"category":380,"image":436,"draft":384},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":438,"title":439,"description":440,"published":441,"category":380,"image":442,"draft":384},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":444,"title":445,"description":446,"published":447,"category":380,"image":448,"draft":384},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":450,"title":451,"description":452,"published":453,"category":380,"image":454,"draft":384},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":456,"title":457,"description":458,"published":459,"category":380,"image":460,"draft":384},"\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":462,"title":463,"description":464,"published":465,"category":380,"image":466,"draft":384},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":468,"title":469,"description":470,"published":471,"category":380,"image":472,"draft":384},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":474,"title":475,"description":476,"published":477,"category":380,"image":478,"draft":384},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":480,"title":481,"description":482,"published":483,"category":429,"image":484,"draft":384},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":486,"title":487,"description":488,"published":489,"category":429,"image":490,"draft":384},"\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":492,"title":493,"description":494,"published":495,"category":429,"image":496,"draft":384},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":498,"title":499,"description":500,"published":501,"category":380,"image":502,"draft":384},"\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":504,"title":505,"description":506,"published":507,"category":380,"image":508,"draft":384},"\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":510,"title":511,"description":512,"published":513,"category":380,"image":514,"draft":384},"\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":414,"title":5,"description":383,"published":415,"category":380,"image":401,"draft":384},{"path":517,"title":518,"description":519,"published":520,"category":380,"image":521,"draft":384},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Десять інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":523,"title":524,"description":525,"published":526,"category":380,"image":527,"draft":384},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":529,"title":530,"description":531,"published":532,"category":380,"image":533,"draft":384},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":535,"title":536,"description":537,"published":538,"category":380,"image":539,"draft":384},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":541,"title":542,"description":543,"published":544,"category":380,"image":545,"draft":384},"\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":302,"title":547,"description":548,"published":549,"category":380,"image":550,"draft":384},"Ключ 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":552,"title":553,"description":554,"published":555,"category":429,"image":556,"draft":384},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":558,"title":559,"description":560,"published":561,"category":380,"image":562,"draft":384},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":564,"title":565,"description":566,"published":567,"category":429,"image":568,"draft":384},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":570,"title":571,"description":572,"published":573,"category":380,"image":574,"draft":384},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":139,"title":576,"description":577,"published":578,"category":380,"image":579,"draft":384},"Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":581,"title":582,"description":583,"published":584,"category":380,"image":585,"draft":384},"\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":587,"title":588,"description":589,"published":590,"category":380,"image":591,"draft":384},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":593,"title":594,"description":595,"published":596,"category":429,"image":597,"draft":384},"\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":599,"title":600,"description":601,"published":602,"category":429,"image":603,"draft":384},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":605,"title":606,"description":607,"published":608,"category":380,"image":609,"draft":384},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":611,"title":612,"description":613,"published":614,"category":380,"image":615,"draft":384},"\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":617,"title":618,"description":619,"published":620,"category":429,"image":621,"draft":384},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":623,"title":624,"description":625,"published":626,"category":380,"image":627,"draft":384},"\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":629,"title":630,"description":631,"published":626,"category":380,"image":632,"draft":384},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":228,"title":634,"description":635,"published":636,"category":380,"image":637,"draft":384},"Нові API-ключі Supabase: який із них безпечний у застосунку?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":639,"title":640,"description":641,"published":642,"category":429,"image":643,"draft":384},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":645,"title":646,"description":647,"published":648,"category":380,"image":649,"draft":384},"\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":651,"title":652,"description":653,"published":648,"category":429,"image":654,"draft":384},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":362,"title":656,"description":657,"published":658,"category":429,"image":659,"draft":384},"Три способи зробити резервну копію бази Supabase, і чого бракує","Панель, pg_dump і керований сервіс. Що насправді зберігає кожен спосіб, що тихо лишає осторонь і який із них переживе втрату акаунта.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":67,"title":661,"description":662,"published":658,"category":380,"image":663,"draft":384},"Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1790150956275]