Writing5 min read

Building the Plumbing for Custom Software

By Kevin Chan

Building the Plumbing for Custom Software

I build internal tools for a living. Lots of them. Different industries, different teams, different problems. Custom reporting for one client. A field operations app for another. An intake workflow that sits between three systems for a third. No two of them look the same on the surface.

Underneath, they're the same.

Every internal tool I've ever built needs the same handful of things. Someone has to log in. Someone has to be allowed to do this and not allowed to do that. Something needs to fire off a notification. Something needs to write down what just happened. Someone, eventually, is going to ask what it's costing. The business problem on top is unique. The plumbing underneath is not.

That's what this post is about. The plumbing.

Building software is fast now. Genuinely fast. The thing that used to take a team three months can be built in a week, sometimes a day. That part is solved.

The hard part moved.

Now it’s the plumbing. The stuff every piece of software in your business needs to be safe, legible, and worth running. Login. Permissions. Notifications. An audit trail. A way to see what it’s costing you. Boring infrastructure. Required infrastructure. The part nobody wants to think about, and the part that decides whether the fast new app you just built is something you can actually deploy in your business or something that sits in a folder labeled “demos.”

What changed

For most of my career, the cost of writing a piece of custom software for a business was the writing. You’d scope it, design it, build it, test it, ship it. Six months on the low end. A year was normal. The plumbing came along for the ride because you had to build the whole thing anyway. Auth. Logging. Roles. All of it baked in as you went.

That world is gone.

The build itself is now the cheapest part. A working app, opinionated to the business, custom to the workflow, can be put together in days. The cost has shifted from “can we build this” to “can we put it somewhere it won’t hurt us.”

Why release has to change

When a build takes a year, you can afford a release process that takes a quarter. You can afford a stage gate review, a security review, a UAT cycle, a phased rollout, a runbook. The release process was a tax that scaled to the build.

When a build takes a week, that release process is the build. You’ve inverted the cost structure of the entire thing. You can build ten apps in the time it takes to release one, and that’s the wrong direction.

So release has to change. It has to become a property of the environment, not a project of its own.

The way that works is by building the plumbing once. Not for one app. For every app, every workflow, every internal tool you’re going to spin up over the next five years. Build it once, build it right, and then every new piece of software lands on top of it the same way.

The plumbing

Here’s the functional layer I’d build into any organization that’s about to start shipping custom software at speed.

Identity. Sign in with Google. Sign in with Entra ID for Microsoft shops. Pick the one you already use and never write a login screen again. Your team already has accounts. Your offboarding is already wired up. When someone leaves, they lose access to everything. This is the single biggest unlock in modern internal software and it costs nothing.

RBAC. Role based access. Who can see this. Who can edit this. Who can approve this. Defined once, at the organization level, and respected by every app you build. Not reinvented per app. Not “well in this tool, finance can see everything, but in that tool, only the lead can.” One model. Centrally managed.

Notifications. Every app needs to tell someone something. Email, Slack, Teams, whatever your business runs on. Wire it once. Every app sends through the same pipe, using the same template language, hitting the same channels. The user controls their preferences in one place. You don’t end up with seven different notification settings panels.

Audit trail. Who did what, when, in which app. Append only. Searchable. Boring. If something goes wrong six months from now, this is the system that tells you whether it was a person, a bug, or a process. Without it, you’re guessing.

Usage and cost. Every app should know how often it’s being used, by whom, and what it’s costing to run. Compute, API calls, storage, AI tokens. If you can’t see it, you can’t decide whether to keep it. Most internal tools die not because they’re bad but because nobody can tell if they’re worth it.

That’s it. That’s the layer.

Why this is the whole game

If you build those five things once, the cost of every new piece of software collapses. You’re not building login. You’re not building permissions. You’re not deciding how notifications should work for the fourth time. You’re building the thing that actually matters to the business, the thing only your business needs, and dropping it onto the plumbing.

The app becomes the interesting part again. The way it should be.

And release stops being a project. It becomes “did the new app respect the plumbing.” Yes or no. If yes, ship it. If no, fix it before it ships. That’s the gate. That’s the whole gate.

How to apply it

Three things, in order.

One. Decide who your identity provider is. If you’re on Google Workspace, it’s Google. If you’re on Microsoft 365, it’s Entra ID. Don’t build anything else. Don’t use a third party login system you’ll have to babysit. Use the one your team already authenticates against every morning.

Two. Pick or build the rest of the plumbing. RBAC, notifications, audit trail, usage and cost. You can buy pieces of this. You can build pieces of this. What matters is that you choose, document, and commit. Every new app uses the same plumbing or it doesn’t ship.

Three. Make the plumbing a release gate, not a release process. When a new internal app is ready, the question is simple. Does it use the identity provider. Does it respect the RBAC model. Does it send notifications through the right pipe. Does it write to the audit trail. Is its usage and cost visible. Five checks. Yes or no.

If yes, it ships.

The reason

The reason to do this is not engineering elegance. It’s that you’re about to be in a world where your business runs on dozens of small, opinionated, custom built pieces of software. Each one fits a workflow. Each one was cheap to build. Each one is going to be a problem if you don’t have a single answer for who can use it, how it tells you things, what it remembers, and what it costs.

The build is no longer the bottleneck. The plumbing is.

Get the plumbing right and you get to spend the next five years building software the way it always should have been built. Custom to your business. Cheap to make. Easy to retire. Worth running.