Mayor

190 posts

Mayor banner
Mayor

Mayor

@techmayorr

Software engineer, accidentally a designer too. Building useful products for 7+ years - Flutter | Rust

Katılım Eylül 2019
778 Takip Edilen1.1K Takipçiler
Cagatay Ulusoy
Cagatay Ulusoy@ulusoyapps·
I wrote up a postmortem about what happened: ulusoyca.medium.com/how-a-two-year… In April my @FlutterDev + @Firebase app was on stage at the Google Cloud Next Developer Keynote. Three weeks later a bot drained €3,167 from the same project overnight and got it suspended by Google. All resolved now — suspension lifted, app back online, billing reviewed. I am sharing the full postmortem because it can be helpful to a lot of indie devs. Thanks to @puf and the Firebase team @sgnagnarella @Thevi_S for their support on diagnosis!
Cagatay Ulusoy@ulusoyapps

The GCP project of my @FlutterDev @Firebase app got suspended this weekend for abuse, after a single day of €3,167 in unauthorized Gemini API charges. The root cause turned out to be a #Firebase Hosting default that is hard to know about. Worth sharing what I learned. I thought the Firebase and Google Cloud project was clean and safe. Client uses Firebase AI Logic (proxy, no on-device Gemini key) with App Check via Play Integrity / App Attest. The suspension email said "key published on public sources." But: my GitHub repo is private and was never public. flutter build web was never run for this project. Where was the leak surface? Google AI Studio showed three Gemini-callable keys. Two tight (server-side). One was a "Browser key (auto created by Firebase)" — Unrestricted, since Nov 2024. That was the web app in my generated firebase_options.dart, from when I configured Flutter web at project init. Here's the part I didn't know about: Firebase Hosting auto-serves your web SDK config at a reserved URL — https://.web.app/__/firebase/init.json — as plain JSON, unauthenticated, to anyone. It includes apiKey, appId, projectId, authDomain. This endpoint is active whenever you have (a) a registered web app in Firebase Console + (b) any Hosting deploy. Contents of the deployed site are irrelevant. Mine was a simple CSS landing page that doesn't reference Firebase JS SDK at all. Endpoint leaked the key anyway. Bots scrape *.web.app/__/firebase/init.json because the pattern is universal across every Firebase project. Mine got picked up, the key was Unrestricted (= usable for any enabled API), and someone burned €3K of Gemini inference in a few hours. Project reinstated after appeal; outstanding balance still in review. Lessons I missed: - Auto-generated browser keys are Unrestricted by default (at least the time project was created). Always add HTTP referrer + API restrictions at creation. - Don't register a web app unless you use the JS SDK. - Set a Gemini spend cap + budget alert. €100/day cap. You can easily do this in Google AI Studio What I would ask the Firebase team: — Browser keys should default to restricted (HTTP referrer to project domains, API restriction to Firebase services) -> not sure this has changed after the date I created the project. — Reserved __/firebase/init.json should be opt-in. Static websites hosted with Firebase Web hosting do not need the API key info. — Firebase Console should warn when a key has been Unrestricted for >N days. Google AI Studio warns when you visit API keys page, but it should be visible on homepage. — Default-on spend caps for Generative Language API. TLDR; "Private repo" is not a meaningful security boundary when the key has another publicly-reachable surface. Audit not just your code, but every endpoint your project ID exposes including the ones the platform creates for you without telling you. Always manually verify API restrictions.

English
1
7
46
7.4K
Cagatay Ulusoy
Cagatay Ulusoy@ulusoyapps·
The GCP project of my @FlutterDev @Firebase app got suspended this weekend for abuse, after a single day of €3,167 in unauthorized Gemini API charges. The root cause turned out to be a #Firebase Hosting default that is hard to know about. Worth sharing what I learned. I thought the Firebase and Google Cloud project was clean and safe. Client uses Firebase AI Logic (proxy, no on-device Gemini key) with App Check via Play Integrity / App Attest. The suspension email said "key published on public sources." But: my GitHub repo is private and was never public. flutter build web was never run for this project. Where was the leak surface? Google AI Studio showed three Gemini-callable keys. Two tight (server-side). One was a "Browser key (auto created by Firebase)" — Unrestricted, since Nov 2024. That was the web app in my generated firebase_options.dart, from when I configured Flutter web at project init. Here's the part I didn't know about: Firebase Hosting auto-serves your web SDK config at a reserved URL — https://.web.app/__/firebase/init.json — as plain JSON, unauthenticated, to anyone. It includes apiKey, appId, projectId, authDomain. This endpoint is active whenever you have (a) a registered web app in Firebase Console + (b) any Hosting deploy. Contents of the deployed site are irrelevant. Mine was a simple CSS landing page that doesn't reference Firebase JS SDK at all. Endpoint leaked the key anyway. Bots scrape *.web.app/__/firebase/init.json because the pattern is universal across every Firebase project. Mine got picked up, the key was Unrestricted (= usable for any enabled API), and someone burned €3K of Gemini inference in a few hours. Project reinstated after appeal; outstanding balance still in review. Lessons I missed: - Auto-generated browser keys are Unrestricted by default (at least the time project was created). Always add HTTP referrer + API restrictions at creation. - Don't register a web app unless you use the JS SDK. - Set a Gemini spend cap + budget alert. €100/day cap. You can easily do this in Google AI Studio What I would ask the Firebase team: — Browser keys should default to restricted (HTTP referrer to project domains, API restriction to Firebase services) -> not sure this has changed after the date I created the project. — Reserved __/firebase/init.json should be opt-in. Static websites hosted with Firebase Web hosting do not need the API key info. — Firebase Console should warn when a key has been Unrestricted for >N days. Google AI Studio warns when you visit API keys page, but it should be visible on homepage. — Default-on spend caps for Generative Language API. TLDR; "Private repo" is not a meaningful security boundary when the key has another publicly-reachable surface. Audit not just your code, but every endpoint your project ID exposes including the ones the platform creates for you without telling you. Always manually verify API restrictions.
Cagatay Ulusoy tweet media
English
5
8
58
11.7K
LEYE
LEYE@leyeConnect·
Work continues 🚧👷🏿‍♂️
LEYE tweet media
English
29
30
715
11.3K
Mayor retweetledi
Pratham
Pratham@Prathkum·
Unpopular opinion: AI made the world super competitive for mediocre people.
English
299
222
4.3K
213.9K
Mayor
Mayor@techmayorr·
Apple needs to replace Siri with Claude or gpt
English
0
0
1
46
Mayor retweetledi
Flutter
Flutter@FlutterDev·
Introducing Agent Skills for Flutter and Dart to give your AI tools domain-specific expertise 📓 These initial core Skills are designed to handle the most common Flutter development hurdles. Learn how to start using them in your workflow → goo.gle/4uBRR6M
GIF
English
8
81
411
40.6K
Mayor
Mayor@techmayorr·
@Yohanansoltd Claude doesn’t create the exact site to avoid copyright, a better approach would be - go to developer tools -> inspect elements, click on the section you want, then copy elements, this way you can combine multiple sections to make your site unique.
English
1
0
0
95
Mayor
Mayor@techmayorr·
Rebuilt agentation by @benjitaylor in Flutter. Basically, you click on widgets, add notes, and copy markdown. Paste the output into Claude Code, Codex, or any AI tool. Genuinely useful so far. #Flutter Link below ↓
English
3
4
15
503
Mayor
Mayor@techmayorr·
@akinkunmi With right architecture setup, features gating at the end, most cases for personal projects we figure things out as we build, so deciding the free vs paid features comes towards the end. what’s your approach?
English
0
0
2
150
Titanium
Titanium@akinkunmi·
When working on SaaS projects, do you build out all the features first and then add feature-gating and billing, or do you build with gating from the beginning?
English
73
8
178
18.2K
Mayor
Mayor@techmayorr·
@SEGVeenstra Same, I picked blue before I read the comments
English
0
0
1
12
Stephan E.G. Veenstra 💙
Stephan E.G. Veenstra 💙@SEGVeenstra·
Everyone discussing the red vs blue button dilemma, and I find it interesting. When I first heard it, I thought "obviously blue". Then after reading comments it does logically make sense to pick red. The issue lies with not knowing what everyone else is thinking.
English
2
0
1
118
lotamchi
lotamchi@lottabydesign·
i started this project in march, i gave myself a couple days to ship. my thinking was i have ai, that guy will figure it out, how hard can it be but the day came and i had nothing i wanted to ship. being a designer doesn't help. i will always keep filing until polish is achieved now it's april and i've pivoted direction more times than i planned. most of my problems came from unintentionally tryin to outsource my thinking to ai. in hindsight, that's like shooting myself in the foot. The project is finally here! At least MVP version. Court Atlas started as globe first, directory of names and addresses. today i've reframed the product to a guide book for tennis enthusiasts who ask "I'm here, how do I actually play?" enjoy: court-atlas.vercel.app share all the bugs and suggestions :)
lotamchi@lottabydesign

spent an unreasonable amount of time obsessing how and what court meta data will be visualised in the gallery. settled on surface type for now, using visual encoding and linear interpolation. even though i can't 100% verify these surface type counts for most cities, i'm enjoyin the process of crafting and polishin this bit

English
14
34
171
7.8K
Mayor
Mayor@techmayorr·
Design engineer role still doesn't make sense to me. you want someone with no dev experience to tweak a live app I'm working on.
English
0
1
0
79
LEYE
LEYE@leyeConnect·
mid-fi
LEYE tweet media
Eesti
23
26
541
37.2K
Mayor
Mayor@techmayorr·
Bugs were already unavoidable. AI made them worse. Most engineers are shipping faster with AI, but debugging slower with it too. Because when the AI writes the code, you skip the part of your brain that would've caught the bug as you typed. So I wrote down the exact playbook I use to debug AI-assisted apps:
Mayor@techmayorr

x.com/i/article/2046…

English
0
0
1
54
Drapz
Drapz@drapzdesigns·
starting a private group for designers. share work, ask for opinions, share your insights, learn from each other, grow together. right now i’m letting in a small group of people who are serious. comment or dm to get in.
English
426
3
579
25.8K
Mayor retweetledi
Suhas
Suhas@zuess05·
Every single person coding with AI right now: > Get an idea at 11 PM. > Build the entire app with Claude by 3 AM. > Realize you actually have to talk to humans to get sales. > Panic and start a new project to avoid marketing. Can we coin a term for whatever mental illness this is? 😭
English
286
175
3.3K
225.5K