[{"data":1,"prerenderedAt":999},["ShallowReactive",2],{"blog-uk-api-key-leaked-what-to-do":3,"blog-index-uk":646},{"id":4,"title":5,"body":6,"category":602,"cover":603,"coverAlt":604,"description":605,"draft":606,"extension":607,"faq":608,"image":623,"keywords":624,"meta":633,"navigation":634,"ogTitle":635,"path":636,"published":637,"seo":638,"stem":639,"tldr":640,"updated":637,"__hash__":645},"blog_uk\u002Fblog\u002Fapi-key-leaked-what-to-do.md","Ваш API-ключ витік. Порядок дій",{"type":7,"value":8,"toc":588},"minimark",[9,13,16,21,24,32,35,57,65,69,72,79,82,88,94,100,104,267,270,280,302,306,309,363,368,372,375,382,385,388,392,395,404,409,414,424,428,431,434,437,440,445,449,455,463,474,483,501,510,527,538,542,580],[10,11,12],"p",{},"Повідомлення найчастіше приходить зі звіту сканера, від GitHub, який пише, що в\nодному з ваших репозиторіїв знайшовся секрет, або від когось, хто натиснув F12\nна вашому сайті й надіслав скриншот. Хай яким шляхом воно до вас дійшло, тепер\nви знаєте, що ваш API-ключ витік, і не знаєте, що робити першим.",[10,14,15],{},"Ось частина, яку посібник за посібником розуміє неправильно: вони дають одну\nвідповідь на будь-який ключ, і ця відповідь завжди «ротуйте». Деякі з тих\nключів мають бути публічними, і робити з ними не треба нічого. Серед решти одні\nтихо нарощують рахунок, поки ви це читаєте, а інші завдали всієї своєї шкоди в\nдень деплою. Це три різні ситуації, і перший крок у кожній свій.",[17,18,20],"h2",{"id":19},"спершу-чи-цей-ключ-узагалі-секрет","Спершу: чи цей ключ узагалі секрет?",[10,22,23],{},"Часто ні, і числа перекошені достатньо, щоб сказати це прямо.",[10,25,26,27,31],{},"Ми просканували 31 056 живих застосунків і прочитали JavaScript, який кожен із\nних віддає браузеру. Перевірка, що шукає облікові дані, змогла відповісти на\nвсіх, і 1 332 повернулися щонайменше з одним ключем, вартим попередження.\n",[28,29,30],"strong",{},"1 142 з них були ключами Google API"," — єдиний тип у цій групі, який зазвичай\nлежить саме там, де йому й місце.",[10,33,34],{},"Ключ Google API на вебсторінці — це те, завдяки чому працює Google Maps. Ключ\nкаже, який проєкт платить, а те, що не дає незнайомцеві витрачати ваші гроші, —\nце обмеження на ключі, а не його таємність. Власна настанова Google пряма щодо\nобох половин: \"Unrestricted API keys are insecure\" та \"You are financially\nresponsible for charges caused by abuse of unrestricted API keys.\" Полагодити\nтакий ключ означає відкрити його в Cloud Console і додати два обмеження: одне\nназиває ваш сайт, друге — ті API, які ви справді викликаєте. Сам ключ при цьому\nне змінюється ніколи.",[10,36,37,38,42,43,46,47,50,51,56],{},"Друга родина, якій місце в браузері, — публічні ключі. Ключ Stripe ",[39,40,41],"code",{},"pk_live_"," і\nключ Supabase ",[39,44,45],{},"sb_publishable_"," або ",[39,48,49],{},"anon"," зроблені так, щоб їх читав кожен ваш\nвідвідувач.\n",[52,53,55],"a",{"href":54},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Які ключі безпечні у вашому фронтенді","\n— це версія тієї ж перевірки на чотири символи.",[10,58,59,60,64],{},"Якщо не хочеться переглядати бандл руками, наше безкоштовне сканування читає\nваш живий сайт, перелічує ключі, які видно ззовні, і каже, якого типу кожен із\nних: ",[52,61,63],{"href":62},"\u002Fsecurity-scanner","просканувати застосунок",". Це займає близько 20 секунд\nі не потребує облікового запису.",[17,66,68],{"id":67},"мій-api-ключ-витік-що-робити-першим","Мій API-ключ витік. Що робити першим?",[10,70,71],{},"Зʼясуйте, чи є на ключі лічильник.",[10,73,74,75,78],{},"Ключ із лічильником тарифікує вам кожен запит. Ключ Google, ключ OpenAI, ключ\nAnthropic і ключ AWS з неправильними правами позаду — усе це лічильники: чужий\nтрафік падає у ваш рахунок, у темпі, який обирає та людина і якого ви не\nбачите. Ключ без лічильника натомість читає або пише ваші дані. Ключ Supabase\n",[39,76,77],{},"service_role"," — найчистіший приклад, і ніщо в ньому не коштує грошей за\nгодину.",[10,80,81],{},"Це одне питання і задає порядок.",[10,83,84,87],{},[28,85,86],{},"Якщо на ключі є лічильник, зупиніть його зараз."," Функція, яка ним\nкористувалася, буде зламана, доки ви не викотите заміну, і це правильний обмін,\nбо рахунок — єдина частина цієї історії, яка продовжує рости, поки ви плануєте.",[10,89,90,93],{},[28,91,92],{},"Якщо ключ читає дані й був опублікований у вашому бандлі, читання вже\nсталося."," Копія є в кожного відвідувача, який завантажив сторінку, і в кожного\nробота, що шукав саме цей рядок. Нічого не погіршиться, поки ви встановлюєте\nправильний порядок, а зробити треба головне: не замкнути себе поза власним\nзастосунком дорогою.",[95,96],"diagram",{"alt":97,"caption":98,"src":99},"Дві смуги, кожна починається з того самого ключа. У верхній ключ веде до циферблата, стрілка якого пройшла добру частину шкали, і далі до стосу монет, усе бурштинове. У нижній ключ веде до таблиці, усі рядки якої горять червоним, а на місці циферблата стоїть порожнє пунктирне коло.","Верхній ключ коштує вам грошей, поки ви це читаєте. Нижній зробив усе, що міг, у день деплою.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fdoes-it-have-a-meter-1600x660.png",[17,101,103],{"id":102},"що-насправді-вміє-кожен-тип-ключа","Що насправді вміє кожен тип ключа",[105,106,107,129],"table",{},[108,109,110],"thead",{},[111,112,113,117,120,123,126],"tr",{},[114,115,116],"th",{},"Ключ",[114,118,119],{},"Витрачає гроші",[114,121,122],{},"Читає ваші дані",[114,124,125],{},"Чи можна натомість обмежити?",[114,127,128],{},"Чи ламає застосунок заміна?",[130,131,132,154,169,188,205,227,248],"tbody",{},[111,133,134,142,145,148,151],{},[135,136,137,138,46,140],"td",{},"Supabase ",[39,139,45],{},[39,141,49],{},[135,143,144],{},"Ні",[135,146,147],{},"Лише рядки, які дозволяють ваші правила",[135,149,150],{},"Його місце в браузері",[135,152,153],{},"Не стосується",[111,155,156,161,163,165,167],{},[135,157,158,159],{},"Stripe ",[39,160,41],{},[135,162,144],{},[135,164,144],{},[135,166,150],{},[135,168,153],{},[111,170,171,177,180,182,185],{},[135,172,173,174],{},"Google ",[39,175,176],{},"AIza…",[135,178,179],{},"Так, у ваш рахунок Cloud",[135,181,144],{},[135,183,184],{},"Так, і Google радить спершу спробувати це",[135,186,187],{},"Обмеження ні. Ротація може.",[111,189,190,193,196,199,202],{},[135,191,192],{},"Ключ OpenAI або Anthropic",[135,194,195],{},"Так, у темпі незнайомця",[135,197,198],{},"Файли та асистенти в проєкті",[135,200,201],{},"Публічного варіанта не існує",[135,203,204],{},"Так, доки його не триматиме ваш сервер",[111,206,207,215,218,221,224],{},[135,208,158,209,46,212],{},[39,210,211],{},"sk_live_",[39,213,214],{},"rk_live_",[135,216,217],{},"Так",[135,219,220],{},"Так, клієнти й записи про платежі",[135,222,223],{},"Обмежений ключ і є вузькою версією",[135,225,226],{},"Ні, є вікно на сім днів",[111,228,229,236,239,242,245],{},[135,230,231,232,235],{},"AWS ",[39,233,234],{},"AKIA…"," разом із секретною половиною",[135,237,238],{},"Так, зокрема обчислення погодинно",[135,240,241],{},"Ваші бакети S3",[135,243,244],{},"Deactivate, і це оборотно",[135,246,247],{},"Ні, можна тримати два ключі водночас",[111,249,250,257,259,262,264],{},[135,251,137,252,46,255],{},[39,253,254],{},"sb_secret_",[39,256,77],{},[135,258,144],{},[135,260,261],{},"Кожен рядок у кожній таблиці",[135,263,144],{},[135,265,266],{},"Так, на старішому проєкті",[10,268,269],{},"Дві примітки до цієї таблиці, бо обидві змінюють наступний крок.",[10,271,272,273,276,277,279],{},"Ключ доступу AWS — це два рядки: ідентифікатор, що починається з ",[39,274,275],{},"AKIA",", і\nсекретна половина, і AWS вимагає їх разом, щоб підписати запит. Тож рядок\n",[39,278,275],{}," сам по собі в бандлі використати не можна, а причина однаково вважати це\nтерміновим у тому, що обидві половини майже завжди вставляють разом. Відкрийте\nфайл і пошукайте другу, перш ніж вирішувати, у якому ви випадку.",[10,281,282,283,287,288,287,292,296,297,301],{},"Подробиці щодо кожного постачальника живуть у нього ж:\n",[52,284,286],{"href":285},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","ключ OpenAI",",\n",[52,289,291],{"href":290},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","ключ Google API",[52,293,295],{"href":294},"\u002Fblog\u002Fstripe-secret-key-in-frontend","секретний ключ Stripe"," і\n",[52,298,300],{"href":299},"\u002Fblog\u002Frotate-supabase-service-role-key","ключ service_role у Supabase",", єдиний\nзі своєю власною процедурою.",[17,303,305],{"id":304},"зупинити-ключ-і-замінити-ключ-це-дві-різні-кнопки","Зупинити ключ і замінити ключ — це дві різні кнопки",[10,307,308],{},"Кожен постачальник у тій таблиці дає обидві, а паніка хапається за другу.",[310,311,312,319,338,347],"ul",{},[313,314,315,318],"li",{},[28,316,317],{},"Google."," Обмеження ключа не змінює сам рядок, тож ваш застосунок працює\nдалі. Їхня настанова з безпеки ставить це попереду всього: \"First try to\nrestrict your API keys\", а ротація йде третім варіантом згори, на випадок,\nколи обмеження неможливе.",[313,320,321,324,325,328,329,333,334,337],{},[28,322,323],{},"Stripe."," ",[28,326,327],{},"Expire key"," зупиняє ключ сам по собі, без жодної заміни. Їхня\nпозиція щодо того, коли цим користуватися, без жодних півтонів: \"If a\nrestricted or secret API key is exposed or compromised, rotate it immediately\neven if you aren't sure anyone saw it.\" Вони ще й розводять два слова, які всі\nвживають як синоніми. ",[330,331,332],"em",{},"Exposure"," — це коли ключ став видимим там, де не мав\nби. ",[330,335,336],{},"Compromise"," — це доказ, що хтось ним скористався.",[313,339,340,324,343,346],{},[28,341,342],{},"AWS.",[28,344,345],{},"Deactivate"," — це той самий орган керування, і корисне в ньому те,\nщо дію можна скасувати. AWS каже взагалі не видаляти старий ключ, поки ви ще\nперевіряєте: \"we recommend that you do not immediately delete the first access\nkey. Instead, choose Actions and then choose Deactivate.\" Якщо виявиться, що\nщось забуте ним досі користується, ви вмикаєте його назад.",[313,348,349,352,353,355,356,358,359,362],{},[28,350,351],{},"Supabase, на старішому проєкті."," Перемикач один, і він накриває обидва\nзастарілі ключі. ",[39,354,49],{}," і ",[39,357,77],{}," підписані одним секретом, тож\nвимикаючи той, якого ви позбуваєтеся, ви зупиняєте й той, яким користується\nваш фронтенд.\n",[52,360,361],{"href":299},"Чотири кроки, які цього уникають","\nварто прочитати до того, як торкатися перемикача, а не після.",[95,364],{"alt":365,"caption":366,"src":367},"Щит із двома перемикачами. Лівий опущений і намальований бурштиновим, поруч із ним перекреслений ключ. Правий піднятий і намальований бірюзовим, поруч із ним ключ і стрілка, що веде до робочого вікна застосунку.","Два органи керування, і діру закриває лише лівий. За який узятися першим — і є рішенням, про яке ця стаття.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Ftwo-switches-1600x600.png",[17,369,371],{"id":370},"прочитати-журнал-за-період-коли-ключ-був-назовні","Прочитати журнал за період, коли ключ був назовні",[10,373,374],{},"Вікно відкривається деплоєм, який уперше випустив ключ, і закривається тоді,\nколи ви його зупинили. Саме за цим проміжком дат ви фільтруєте журнал\nпостачальника.",[10,376,377,378,381],{},"Журнал веде кожен постачальник із таблиці. Stripe показує журнали запитів\nокремого ключа — через меню з трьома крапками поруч із ним на сторінці API\nKeys. AWS без жодного налаштування ставить дату останнього використання на\nкожен ключ доступу в консолі IAM і записує самі виклики в CloudTrail. Google\nведе графіки використання по ключах у Cloud Console, і це та сама перевірка, яку\nїхня настанова радить зробити, перш ніж щось міняти в ключі. Supabase зберігає\nжурнали API та бази даних проєкту, а\n",[52,379,380],{"href":299},"як звузити вікно на ключі Supabase","\nкаже, що саме в них шукати.",[10,383,384],{},"Ви шукаєте трафік, якого не можете пояснити: запити до таблиць чи ендпоїнтів,\nяких ваш застосунок ніколи не торкається, обсяг у години, коли ним ніхто не\nкористувався, видалення, яких ніхто не робив. Далі подивіться на самі дані, бо\nзвернення в підтримку про запис, що змінився сам собою, — це спосіб, у який\nбільшість таких історій і викривають, і приходить воно за кілька тижнів.",[10,386,387],{},"Часто певності бути не може, і Stripe каже те саме про власне виявлення:\n\"Stripe doesn't guarantee detection of all exposed or compromised keys.\" Тож\n«нічого в журналі» — це результат, і його варто записати разом із проміжком\nдат.",[17,389,391],{"id":390},"ротація-без-зупинки-застосунку","Ротація без зупинки застосунку",[10,393,394],{},"Троє з чотирьох постачальників вище дають вікно, у якому старий і новий ключі\nпрацюють обидва, і саме це рятує від простою.",[10,396,397,399,400,403],{},[28,398,323],{}," \"When you rotate a key in the Dashboard, both the old and new keys\nwork for up to 7 days.\" У діалозі є ще варіант ",[28,401,402],{},"Now",", і їхня документація\nкаже прямо: якщо обрати його, старий ключ буде видалено. Це кнопка для\nаварійного випадку з лічильником, а не для спокійної міграції. Їхня порада, коли\nвідпускати старий, — це вимірювання, а не дата: перевірте його журнали запитів і\nдайте йому спливти лише після того, як обсяг запитів кілька годин чи днів\nтримався на нулі.",[10,405,406,408],{},[28,407,317],{}," Ротація створює новий ключ з усіма обмеженнями старого і, їхніми\nсловами, \"both the old and new key are accepted\" протягом вікна, поки ви\nпереводите застосунки. Якщо видалити старий зарано і щось зламається, дорога\nназад є: видалений ключ Google API можна відновити протягом 30 днів.",[10,410,411,413],{},[28,412,342],{}," Послідовність є в їхній документації, і вона починається з нового\nключа: створіть другий ключ доступу, поки перший ще активний, переведіть на\nнього кожен застосунок, перевірте дату останнього використання старого,\nдеактивуйте його і лише тоді видаліть. Стеля, яку треба врахувати: користувач\nIAM може тримати щонайбільше два ключі доступу, тож третьому застосунку, який\nдосі на старому ключі, подітися нікуди.",[10,415,416,418,419,355,421,423],{},[28,417,351],{}," Вікна немає. Пряма ротація застарілих\nключів ",[39,420,49],{},[39,422,77],{}," більше не підтримується, тож зробити один із них\nнедійсним — це міграція на нову пару ключів, і саме порядок чотирьох кроків\nтримає застосунок на ногах.",[17,425,427],{"id":426},"він-досі-у-вашій-історії-git","Він досі у вашій історії Git",[10,429,430],{},"Так і є, і документація GitHub про це починається з того, що відправляє вас\nдеінде.",[10,432,433],{},"Їхня сторінка про видалення чутливих даних повертає вас до ключа: \"if the\nsensitive data you need to remove is a secret (e.g. password\u002Ftoken\u002Fcredential),\nas is often the case, then as a first step you need to revoke and\u002For rotate that\nsecret\", а далі: \"Once the secret is revoked or rotated, it can no longer be used\nfor access, and that may be sufficient to solve your problem. Going through the\nextra steps to rewrite the history and remove the secret may not be warranted.\"",[10,435,436],{},"Причина, яку вони називають, — це те, куди force push не дістає. Після\nпереписування історії старі коміти лишаються \"In any clones or forks of your\nrepository\" і \"Directly via their SHA-1 hashes in cached views on GitHub\".\nПідтримка може прибрати кешовані перегляди й посилання в pull request, якщо\nпопросити, і проводить власну межу: вона \"will only assist in the removal of\nsensitive data in cases where we determine that the risk can't be mitigated by\nrotating affected credentials.\" Форк залишає копію собі в будь-якому разі, а\nконтактів його власника GitHub вам не дасть.",[10,438,439],{},"Тож порядок, який вони описують, і є практичним: відкликати ключ, а потім\nвирішувати, чи варте переписування історії своїх побічних ефектів. Відкликання\nдістає до копій, куди переписування не дістає: зокрема до тієї, що в клоні, про\nякий ви не знаєте, і до тієї, що на скриншоті, який хтось зберіг.",[95,441],{"alt":442,"caption":443,"src":444},"Три однакові бляклі документи: форк, чийсь клон і кешований перегляд, і кожен досі тримає той самий бурштиновий ключ. Одна бірюзова лінія проходить через усе зображення і перекреслює всі три ключі.","Той самий ключ у трьох копіях, яких ви не видалите. Відкликання перекреслює всі три за один раз.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fone-line-covers-every-copy-1600x520.png",[17,446,448],{"id":447},"як-не-пустити-наступний-у-бандл","Як не пустити наступний у бандл",[10,450,451,454],{},[28,452,453],{},"Ключ потрапляє у ваш бандл через деплой, а деплої не припиняються."," Кожен із\nних — ще один шанс, що значення, яке ви вписали в панель секретів, опиниться у\nфайлі, який завантажує браузер. Саме тому перевірка, зроблена минулого місяця,\nописує застосунок минулого місяця.",[10,456,457],{},[28,458,459,462],{},[52,460,461],{"href":62},"Наше безкоштовне сканування"," відповідає на питання, з яким\nви сюди прийшли.",[310,464,465,468,471],{},[313,466,467],{},"девʼять перевірок на вашій живій URL-адресі, приблизно за 20 секунд",[313,469,470],{},"кожен ключ, який видно ззовні, не просто знайдений, а віднесений до типу",[313,472,473],{},"оцінка і знахідки, без облікового запису",[10,475,476],{},[28,477,478,482],{},[52,479,481],{"href":480},"\u002Fpricing","Reeve Monitor"," проганяє ті самі перевірки знову, без ваших\nнагадувань.",[310,484,485,488,495,498],{},[313,486,487],{},"усі девʼять перевірок щогодини, для трьох застосунків",[313,489,490,491,494],{},"повідомлення, коли результат ",[28,492,493],{},"змінюється",", щоб ключ, який пішов із нічним\nдеплоєм, не чекав, поки ви зазирнете",[313,496,497],{},"чи відповідає застосунок, кожні 60 секунд",[313,499,500],{},"щомісячний звіт про побачене",[10,502,503],{},[28,504,505,509],{},[52,506,508],{"href":507},"\u002Fsupabase-backups","Reeve Care"," тримає копію вашої бази даних Supabase — для\nтих ключів, які вміють писати.",[310,511,512,515,518,521,524],{},[313,513,514],{},"зашифрована копія щоночі, у місці, куди ваш проєкт не дістає",[313,516,517],{},"кожна копія перевіряється, перш ніж її зарахувати: ми рахуємо рядки в кожній\nтаблиці",[313,519,520],{},"відновлення в один клік, коли воно знадобиться",[313,522,523],{},"а також ваші завантажені файли, щойно ви підключите облікові дані Storage",[313,525,526],{},"усе, що робить Monitor",[10,528,529,530,532,533,537],{},"Ключ, який витік і вміє лише читати, залишає ваші дані там, де вони були. Ключ\n",[39,531,77],{}," чи ключ AWS із правом запису здатен спорожнити таблицю, і жодна\nротація після цього не поверне рядки.\n",[52,534,536],{"href":535},"\u002Fblog\u002Fai-agent-deleted-my-database","День, коли ШІ-агент видалив робочу базу даних","\nпоказує, як це виглядає зсередини.",[17,539,541],{"id":540},"що-зробити-просто-зараз","Що зробити просто зараз",[543,544,545],"key-takeaways",{},[310,546,547,559,562,571,574,577],{},[313,548,549,550,552,553,555,556,558],{},"Визначте ключ, перш ніж його чіпати. Ключ Supabase ",[39,551,49],{}," чи ",[39,554,45],{}," і ключ Stripe ",[39,557,41],{}," лежать там, де мають, а з 1 332 застосунків, де ми знайшли ключ, вартий попередження, у 1 142 був ключ Google API, якому потрібне обмеження, а не ротація.",[313,560,561],{},"Запитайте, чи є на ньому лічильник. Якщо чужі запити падають у ваш рахунок, зупиніть ключ зараз і дайте функції зламатися.",[313,563,564,565,567,568,570],{},"Користуйтеся органом керування, що зупиняє, так само як тим, що замінює: ",[28,566,327],{}," у Stripe, ",[28,569,345],{}," в AWS, обмеження за сайтом і за API в Google.",[313,572,573],{},"Потім замініть його в межах вікна постачальника. Stripe дає сім днів з обома живими ключами, Google приймає обидва, поки ви мігруєте, а AWS дозволяє тримати два ключі доступу водночас.",[313,575,576],{},"Прочитайте журнал постачальника за період між деплоєм і зупинкою і запишіть, що знайшли, зокрема й «нічого».",[313,578,579],{},"Історію Git залиште наостанок. Щойно ключ відкликано, власна настанова GitHub каже, що переписувати історію, можливо, узагалі не варто.",[10,581,582,583,587],{},"Якщо вам зручніше пройти все це списком,\n",[52,584,586],{"href":585},"\u002Fchecklist","10-хвилинний чеклист безпеки"," охоплює цю тему й решту того, що\nварто вимкнути у щойно запущеному застосунку.",{"title":589,"searchDepth":590,"depth":590,"links":591},"",3,[592,594,595,596,597,598,599,600,601],{"id":19,"depth":593,"text":20},2,{"id":67,"depth":593,"text":68},{"id":102,"depth":593,"text":103},{"id":304,"depth":593,"text":305},{"id":370,"depth":593,"text":371},{"id":390,"depth":593,"text":391},{"id":426,"depth":593,"text":427},{"id":447,"depth":593,"text":448},{"id":540,"depth":593,"text":541},"Основи безпеки","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcover-1200x630.png","Картка доступу з намальованим ключем стоїть перед щитом із перемикачами, перший з яких опущений у положення «вимкнено».","API-ключ витік, і ви не знаєте, що робити першим. Не кожен ключ у вашому фронтенді є витоком, а порядок важить більше за швидкість.",false,"md",[609,611,614,617,620],{"q":68,"a":610},"Зʼясуйте, чи може ключ витрачати гроші. Ключ, який тарифікує кожен запит, коштує вам грошей просто зараз, тож зупиніть його негайно і прийміть, що функція, яка ним користувалася, кілька хвилин не працюватиме. Ключ, який лише читає дані, уже прочитано, якщо він був публічним, тож спокійно робіть заміну в порядку, який не замкне вас поза власним застосунком.",{"q":612,"a":613},"Спершу відкликати чи ротувати?","Спершу відкликати, якщо на ключі є лічильник. Зупинити старий ключ і випустити новий у кожного постачальника є двома окремими органами керування, і діру закриває лише перший. Виняток становить ключ, який можна натомість обмежити: Google радить спробувати обмеження за сайтом і за API ще до того, як узагалі ротувати ключ Google API.",{"q":615,"a":616},"Як дізнатися, чи хтось користувався моїм ключем?","Звузьте вікно до періоду між деплоєм, який випустив ключ, і моментом, коли ви його зупинили, і прочитайте журнал постачальника за цей проміжок. Stripe показує журнали запитів по кожному ключу, AWS показує дату останнього використання на ключі доступу і записує виклики в CloudTrail, Google веде графіки використання по ключах, а Supabase зберігає журнали API та бази даних. Ви шукаєте запити до того, чого ваш застосунок ніколи не торкається, і трафік у години, коли ним ніхто не користувався. Часто певності бути не може, і це нормальний результат.",{"q":618,"a":619},"Чи зламає ротація ключа мій застосунок?","Зазвичай ні, якщо скористатися вікном, яке дає постачальник. Stripe тримає старий і новий ключ робочими разом до семи днів. Google випускає новий ключ з обмеженнями старого і приймає обидва, поки ви мігруєте. AWS дозволяє тримати два ключі доступу водночас, тож новий уже живий до того, як піде старий. Виняток становить старіший проєкт Supabase, де перемикач, що вимикає застарілі ключі, забирає з собою й ключ вашого фронтенду.",{"q":621,"a":622},"Ключ лежить у моїй історії Git. Чи досить видалити файл?","Ні, і переписування історії теж навряд чи є відповіддю. Документація GitHub каже спершу відкликати або ротувати секрет, і що після цього вплутуватися в переписування історії може бути вже недоцільно. Force push не дістає до копій у форках і клонах, ані до кешованих переглядів, доступних за хешем коміту. Зробити ключ непридатним покриває всі копії за один раз.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",[625,626,627,628,629,630,631,632],"api ключ витік що робити","витік api ключа","мій api ключ публічний","api ключ скомпрометовано","ротація api ключа","знайшов свій api ключ на github","api ключ у фронтенді","що можна зробити з моїм api ключем",{},true,"API-ключ витік. Що робити, по порядку","\u002Fblog\u002Fapi-key-leaked-what-to-do","2026-10-09",{"title":5,"description":605},"blog\u002Fapi-key-leaked-what-to-do",[641,642,643,644],"Якщо API-ключ витік, перша дія залежить від того, який це ключ. Публічні ключі живуть у вашому фронтенді, і робити з ними не треба нічого.","Якщо це справжній секрет, зʼясуйте, чи може ключ витрачати гроші. Це єдина частина цієї історії, на якій цокає годинник.","Зупинити ключ і замінити ключ у кожного постачальника є двома різними органами керування, і більшість дає вікно, у якому працюють обидва ключі.","Потім прочитайте журнал постачальника за період, коли ключ був назовні, і не чіпайте історію Git, доки ключ не мертвий.","hKPHXZkzah3oKkAYpBY7dpDTC6mb-JDt7WHovFGYKLU",[647,653,659,660,666,672,678,684,690,696,702,708,714,720,727,733,739,744,750,756,762,768,774,780,785,791,797,803,809,815,821,827,833,839,845,850,856,862,868,874,879,885,891,897,903,909,915,921,927,933,939,945,950,955,961,966,972,978,984,989,995],{"path":648,"title":649,"description":650,"published":651,"category":602,"image":652,"draft":606},"\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":654,"title":655,"description":656,"published":657,"category":602,"image":658,"draft":606},"\u002Fblog\u002Fbase44-security-scan","Сканування безпеки Base44: те, що бачить лише воно","Сканування безпеки Base44 перевіряє сім видів проблем зсередини. Ось половина, яку читає тільки воно, і половина, на яку воно ніколи не дивиться.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":636,"title":5,"description":605,"published":637,"category":602,"image":623,"draft":606},{"path":661,"title":662,"description":663,"published":664,"category":602,"image":665,"draft":606},"\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":667,"title":668,"description":669,"published":670,"category":602,"image":671,"draft":606},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" у Supabase, і хибне виправлення","\"No API key found in request\" означає, що запит дійшов до Supabase без ключа. Більшість відповідей натомість вказують на правила вашої бази.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":673,"title":674,"description":675,"published":676,"category":602,"image":677,"draft":606},"\u002Fblog\u002Fis-base44-safe","Чи безпечний Base44? Дані 5 442 застосунків","Чи безпечний Base44? Ми прогнали дев’ять перевірок на 5 442 робочих застосунках Base44. Майже всі отримали B з причин, яких власник ніколи не обирав.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":679,"title":680,"description":681,"published":682,"category":602,"image":683,"draft":606},"\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":685,"title":686,"description":687,"published":688,"category":602,"image":689,"draft":606},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Чи відкритий ваш файл .env? Дванадцять шляхів для перевірки","Чи відкритий ваш файл .env на вашому власному вебсервері? Дванадцять адрес скажуть це за хвилину, а влучання означає, що все в ньому вже публічне.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":691,"title":692,"description":693,"published":694,"category":602,"image":695,"draft":606},"\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":697,"title":698,"description":699,"published":700,"category":602,"image":701,"draft":606},"\u002Fblog\u002Fis-bolt-safe","Чи безпечний Bolt? Що показали 1 123 застосунки Bolt","Чи безпечний Bolt? Ми прогнали 1 123 живі застосунки Bolt через дев’ять перевірок. Хостинг був чистим. Знахідки: ключі й відкриті таблиці в самих застосунках.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":703,"title":704,"description":705,"published":706,"category":602,"image":707,"draft":606},"\u002Fblog\u002Fis-supabase-down-or-your-app","Supabase не працює чи проблема у вашому застосунку? Як розрізнити","Supabase не працює чи зламався ваш застосунок? Пауза, повна база й ваша власна помилка виглядають однаково. Чотири перевірки їх розрізняють.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":709,"title":710,"description":711,"published":712,"category":602,"image":713,"draft":606},"\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":715,"title":716,"description":717,"published":718,"category":602,"image":719,"draft":606},"\u002Fblog\u002Fsupabase-free-plan-limits","Ліміти безкоштовного тарифу Supabase і що стається на кожному","Ліміти безкоштовного тарифу Supabase: 500 МБ бази, 5 ГБ egress і жодних резервних копій. Що стається на кожній межі і що змінює Pro за $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":721,"title":722,"description":723,"published":724,"category":725,"image":726,"draft":606},"\u002Fblog\u002Ftest-your-supabase-backup","Перевірте резервну копію Supabase до того, як вона знадобиться","Як перевірити резервну копію Supabase: відновити в тестовий проєкт, порахувати рядки, увійти й знайти рядок, якого бракує обрізаному файлу.","2026-09-28","Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":728,"title":729,"description":730,"published":731,"category":725,"image":732,"draft":606},"\u002Fblog\u002Fsupabase-backup-github-action","Безкоштовна резервна копія Supabase через GitHub Action і підступ","Резервна копія Supabase через GitHub Action безкоштовна й годиться багатьом застосункам. Робочий процес, потрібний рядок підключення та egress.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":734,"title":735,"description":736,"published":737,"category":725,"image":738,"draft":606},"\u002Fblog\u002Fdownload-your-supabase-backup","Чому ви не можете завантажити резервну копію Supabase","Завантажити резервну копію Supabase на сучасному проєкті не вийде: щоденна копія там фізична. Як це перевірити і як тримати власну копію.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":740,"title":741,"description":742,"published":737,"category":602,"image":743,"draft":606},"\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":745,"title":746,"description":747,"published":748,"category":602,"image":749,"draft":606},"\u002Fblog\u002Fopen-api-endpoint-exposed","Чи є відкритий API-ендпоінт проблемою безпеки? Читайте JSON","Ваше сканування позначило відкритий API-ендпоінт. Чи це важливо, залежить від того, що повернулося, і більшість знайдених належали платформі.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":751,"title":752,"description":753,"published":754,"category":602,"image":755,"draft":606},"\u002Fblog\u002Flovable-security-scan","Сканування безпеки Lovable: чого воно не доведе","Сканування безпеки Lovable: що перевіряють Quick scan і Deep scan, коли запускається кожне, і єдине, чого не доведе жодне сканування зсередини.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":757,"title":758,"description":759,"published":760,"category":725,"image":761,"draft":606},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":763,"title":764,"description":765,"published":766,"category":602,"image":767,"draft":606},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":769,"title":770,"description":771,"published":772,"category":602,"image":773,"draft":606},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":775,"title":776,"description":777,"published":778,"category":602,"image":779,"draft":606},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":294,"title":781,"description":782,"published":783,"category":602,"image":784,"draft":606},"Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":786,"title":787,"description":788,"published":789,"category":602,"image":790,"draft":606},"\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":792,"title":793,"description":794,"published":795,"category":602,"image":796,"draft":606},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":798,"title":799,"description":800,"published":801,"category":602,"image":802,"draft":606},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":804,"title":805,"description":806,"published":807,"category":602,"image":808,"draft":606},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":810,"title":811,"description":812,"published":813,"category":725,"image":814,"draft":606},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":816,"title":817,"description":818,"published":819,"category":725,"image":820,"draft":606},"\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":822,"title":823,"description":824,"published":825,"category":725,"image":826,"draft":606},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":828,"title":829,"description":830,"published":831,"category":602,"image":832,"draft":606},"\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":834,"title":835,"description":836,"published":837,"category":602,"image":838,"draft":606},"\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":840,"title":841,"description":842,"published":843,"category":602,"image":844,"draft":606},"\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":299,"title":846,"description":847,"published":848,"category":602,"image":849,"draft":606},"Як замінити злитий ключ service_role у Supabase","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":851,"title":852,"description":853,"published":854,"category":602,"image":855,"draft":606},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Десять інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":857,"title":858,"description":859,"published":860,"category":602,"image":861,"draft":606},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":863,"title":864,"description":865,"published":866,"category":602,"image":867,"draft":606},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":869,"title":870,"description":871,"published":872,"category":602,"image":873,"draft":606},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":285,"title":875,"description":876,"published":877,"category":602,"image":878,"draft":606},"Ваш ключ API OpenAI відкритий у фронтенді. Замініть його.","Ключ API OpenAI, відкритий у фронтенді, не можна прив'язати до домену. Замініть його сьогодні, перенесіть виклик на свій сервер і обмежте витрати.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":880,"title":881,"description":882,"published":883,"category":602,"image":884,"draft":606},"\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":886,"title":887,"description":888,"published":889,"category":725,"image":890,"draft":606},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":892,"title":893,"description":894,"published":895,"category":602,"image":896,"draft":606},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":898,"title":899,"description":900,"published":901,"category":725,"image":902,"draft":606},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":904,"title":905,"description":906,"published":907,"category":602,"image":908,"draft":606},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":910,"title":911,"description":912,"published":913,"category":602,"image":914,"draft":606},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":916,"title":917,"description":918,"published":919,"category":602,"image":920,"draft":606},"\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":922,"title":923,"description":924,"published":925,"category":602,"image":926,"draft":606},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":928,"title":929,"description":930,"published":931,"category":725,"image":932,"draft":606},"\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":934,"title":935,"description":936,"published":937,"category":725,"image":938,"draft":606},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":940,"title":941,"description":942,"published":943,"category":602,"image":944,"draft":606},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":290,"title":946,"description":947,"published":948,"category":602,"image":949,"draft":606},"Чи є проблемою ключ API Google у вашому браузері?","Ключ API Google у відкритому коді сторінки наш сканер знаходить найчастіше, і зазвичай усе гаразд. Вирішує це одне безкоштовне налаштування.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":535,"title":951,"description":952,"published":953,"category":725,"image":954,"draft":606},"ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":956,"title":957,"description":958,"published":959,"category":602,"image":960,"draft":606},"\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":962,"title":963,"description":964,"published":959,"category":602,"image":965,"draft":606},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":967,"title":968,"description":969,"published":970,"category":602,"image":971,"draft":606},"\u002Fblog\u002Fsupabase-new-api-keys","Нові API-ключі Supabase: який із них безпечний у застосунку?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":973,"title":974,"description":975,"published":976,"category":725,"image":977,"draft":606},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":979,"title":980,"description":981,"published":982,"category":602,"image":983,"draft":606},"\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":985,"title":986,"description":987,"published":982,"category":725,"image":988,"draft":606},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":990,"title":991,"description":992,"published":993,"category":725,"image":994,"draft":606},"\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":54,"title":996,"description":997,"published":993,"category":602,"image":998,"draft":606},"Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1791705965416]