Day 77: The Audit That Made Me Not Ship
Today's plan was to ship a middleware auth-redirect fix — small diff, real security value, natural continuation of the security work from yesterday and the days before it. Instead I audited the file, realized my plan was based on a false premise, and deferred the fix. No application code shipped. Thirty-two days to launch, and the highest-value work I did today was decide not to touch a high-blast-radius file.
That's an uncomfortable outcome to write about, because "I shipped nothing" doesn't sound like progress. But I think today was a good day, and I want to be honest about why.
The plan I walked in with
My handoff document said the middleware currently protects /admin with a server-side session check. I'd flagged this in my running punch list as "one route protected, three more to go" — the three being /dashboard, /settings, and /onboarding. Extending the pattern felt like a bounded, defensive win. Sixty lines of code, one file touched, mirrored from a working reference, low regression risk. Fits the pre-launch security hardening arc from earlier in the week. On paper, exactly the kind of small consistency work you want to do before opening the doors.
I have a rule I try to hold with myself: read the actual files before writing the fix. So before writing any implementation, I asked for an inventory of the current middleware state and how each of the four routes actually guards against unauthenticated access today. Verify first, edit second.
The audit that killed the plan
Every assumption in my plan was wrong.
The middleware doesn't have a server-side session redirect for /admin. It has one narrow check that redirects blocked businesses away from /dashboard, and that's the only conditional in the file. All the auth enforcement I thought lived in middleware actually lives in page-level server components — /dashboard, /settings, /admin, and even a fifth route I hadn't flagged all check the session themselves and redirect if it's missing. There was no working pattern in middleware to mirror because there was no pattern in middleware, period.
Only one of the four routes I was targeting has an actual gap. /onboarding uses a client-side check inside a React effect. The page body starts rendering before the redirect fires. It's the one place my architecture doesn't match my own principles about not trusting the client for auth. That's a real bug — mild, brief, but real.
But the fix means editing the middleware. That file runs on every request that hits the site. Adding auth logic there means adding server-side risk to routes that already work. If I get the API-route carve-out wrong, I break a cron job silently. If I create a redirect loop, every user hits it. This is the kind of thing I've written about before — audit findings are cheap to write down and expensive to close. Thirty-two days from launch, the trade wasn't worth it for a mild rendering flash on one form.
The other thing I decided not to ship
Earlier in the day I'd been planning to harden /api/health — a public endpoint that currently exposes which services my stack uses and calls each of them on every anonymous hit. Technically a real finding. Practically, the endpoint has been open for 76 days and nothing has happened. No cost spike, no error flood, no reconnaissance signal I can see.
I nearly wrote a hardening plan anyway. The write-up escalated the finding from "LOW enumerates stack" to "unauthenticated cost amplification" and it read as compelling until I asked the boring question. Is anyone actually doing this? No. Would I lose sleep if they did? Also no. I'd rotate the token in twenty minutes and ship the fix reactively. Defer the pre-launch scope.
You can see everything I've actually shipped on the security page. This one didn't make it.
What today taught me
Pre-launch risk-taste is a real thing, and I don't think I was taking it seriously enough a week ago. Every hardening finding looks tempting when you read it in isolation. But hardening isn't free — every change is regression surface, every commit is one more thing that could break Stripe or the auth flow on a Sunday morning when I'm not watching. Thirty-two days out, the calculus starts inverting. Small theoretical wins stop being worth their risk of small real losses.
Auditing the middleware was the shipped work today. The plan I threw out was more valuable than the fix I would have shipped, because it stopped me from taking on a regression I couldn't fully test in the runway I have left. That's a strange form of progress. It doesn't show up on the changelog as a code diff. But I think it's the right form for where I'm sitting.
Tomorrow I'll ship something. Today I audited what I wouldn't ship, and I'm calling that a full day.
Written by
The founder of Ominvo
Building review management for single-location small businesses. Join the waitlist →