I opened the subscriber table expecting a quiet list of real people.
What I found instead did not look organic. Hundreds of pending signups stacked up in a steady drip. Truncated addresses. Carrier gateways. The same name typed wrong, then typed again a minute later. It had the rhythm of automation, not curiosity. And every one of those attempts still cost me a confirm email.
That was a useful reminder as a team of one: shipping the feature is not the same as surviving contact with the internet. The open doors need the same care as the product itself.
The internet will find the open door
A plain subscribe form is an open door. So is a contact box. So is any endpoint that accepts an email and does something expensive - like sending mail, writing to a database, or calling an AI model. If it costs you something and costs them almost nothing, they will lean on it until it hurts.
So I treat those doors like product surfaces, not afterthoughts. On Team of One I added Cloudflare Turnstile, a honeypot field humans never see, and stricter email checks so gmail.c stops counting as a person. None of that made the newsletter more fun. It stopped the quiet bleed.
That's the unglamorous half of building in public. You don't get applause for the attack that didn't land.
Anything a stranger can type, another stranger might see
Spam is the loud problem. The quieter one is user-generated content.
The moment your product lets someone upload a photo, leave a name, post a tip, share a result, or save a URL that other people will open, you've invited the whole messy range of human behavior into a place your other users can see. On Feeder Rater, people upload pictures of their setups. On Tap and Call, tappers can land on names, alert messages, and redirect links someone else configured. Little scraps of text and media that feel harmless when you're the only person using the app at 11pm.
They are not harmless once the audience grows.
A text field is not "just a string." It is a surface that can carry junk, abuse, or something another guest should never have to read. An image is not "just a file." It can be the wrong kind of photo, a huge payload meant to burn your storage bill, or something that should never sit next to a brand mark on a live tap page. A URL is not "just a link." It can send a stranger into malware, phishing, or explicit content.
If other people can see it or follow it, you are responsible for what gets through.
How I actually protect that content
I don't run a trust-and-safety department. I run the same kind of checks I already ship in Tap and Call, and I carry that mindset into every Maker Gully product.
- URLs get screened before they go live. On Tap and Call, redirect links, menu links, websites, and safe-mode social URLs go through Google Web Risk for malware and phishing, plus Cloudflare Family DNS for adult and explicit domains. If it fails, it does not get saved. Guests never become the filter.
- Public text gets filtered. Placement names, alert messages, spot names, guest notes - anything another person might read - goes through profanity checks (and PII checks where that matters) before save. "Please choose different wording" is a better product moment than an ugly surprise on someone else's phone.
- Uploads fail closed. Brand images and other files that can appear in front of guests are constrained by type and size, and rejected when they don't meet the bar. Same rule for any photo or attachment that can become someone else's view: accept only what you can defend.
- Make expensive actions prove a human is present. Captchas, honeypots, rate limits - especially on signup, contact forms, and anything that sends email or hits a paid API.
- Separate "accepted" from "visible." Double opt-in for email. For content that can harm someone else if it goes live unchecked, put friction in front of visibility, not behind an apology.
- Watch the meters that spam moves. SES volume, sudden PENDING piles, storage growth, API spend. The attack often shows up as a dashboard spike before it shows up as a headline.
None of this is glamorous. All of it is cheaper than explaining to a real user why your product became someone else's problem.
Trust is part of the product
For the kind of software I ship, the practical work looks like this: keep strangers from burning your email quota for sport, keep an uploaded photo from becoming someone else's problem, and keep the convenient text box from turning into a billboard.
People trust a product that feels tended. Not perfect. Tended. The same way adopting a product means fixing the boring bugs after launch, it also means putting locks on every door your users can walk through - including the ones that look like a simple form field.
That's the reality of being a team of one.
#TeamOfOne #BuildInPublic #IndieHackers #AppSecurity #SideProjects