jp.
← Back to blog

Forge Mobile OS

Forge Mobile OS — The App That Promised Nothing Would Leave the Device

Every morning, someone on my team had to manually run the same WhatsApp attendance poll. I looked at the usual fixes — MacroDroid, Tasker, a bot, a Google Form — and rejected every single one, mostly for the same reason: they all wanted broad Accessibility permissions on my team's phones, for an app built by someone else that I couldn't audit. If anything was going to read screens and tap buttons on our behalf, I wanted to be the one who wrote it, and the one who could look inside it.

So I built it myself. An Android app, its own Accessibility service, one shared automation layer with independent feature modules bolted on as I needed them. No server. No internet permission, on purpose. The entire pitch of the thing, to my own team and to myself, was nothing leaves the device.

Then I did a proper code review of my own app, and found out that wasn't quite true.

Three separate things contradicted the one promise the whole app was built on.

The encrypted key store had a fallback path: if the Android Keystore ever failed to open, it silently wrote the key in plain text instead — while the interface kept calmly showing "encrypted," because nothing told it otherwise. Android's own automatic backup was still switched on, which meant Google's cloud backup had quietly been uploading that key file, along with a full call-history log, off the device the entire time. And an API key I thought I'd secured was riding along in a request URL, which is one of the more well-known ways to leak a secret without noticing.

None of this was subtle once I actually looked. That's the uncomfortable part. I'd built a security-and-privacy tool and hadn't checked the three most basic ways it could betray its own promise.

I fixed all three in the same release and called it the Security Pack — encryption failures now show a visible warning instead of quietly degrading, backup got switched off, the API key moved into a header where it belongs. Then I did something I think is the actual point of this story: I ran the app's own built-in security scanner against itself, and let it flag the app as high risk, the same way it would flag any other app with broad permissions it can't fully vouch for. I use that screen in team security training now. An app that can't survive its own audit doesn't get to lecture anyone about trust.

There's a second story living in the same app that's smaller but still stuck with me. A feature I'd built to flag people going over our work-from-home threshold had a genuine math bug in it — a leave category was being counted where it shouldn't have been, and each person's tracking window was being calculated slightly differently instead of using one shared standard for the whole team. The practical effect was that someone with a legitimately high percentage got quietly left off the list that was supposed to catch exactly that. I fixed the math the same day, and added a small feature I probably should have built from the start — tap any number, and it shows you the exact calculation behind it, so I'm never trusting a percentage I can't personally re-derive.

An app that can't survive its own audit doesn't get to lecture anyone about trust.

I don't think either of these stories makes the app sound impressive. I think that's exactly why they're worth telling. It's easy to build something and describe its intentions accurately. It's a different discipline entirely to go back and check whether the thing you built actually behaves the way you said it would — especially when you're the only one who was ever going to look.

Copied