Infrastructure
Do the Cross-Cutting Work at the Edge
TLS, auth, rate limiting, security headers, upstream certificate validation — the concerns every service shares are the ones no service should reimplement, so terminate them once at a reverse proxy and let every backend inherit them.
- Infrastructure
- Networking
- Security
- Web
Every service behind your front door needs roughly the same boring things: encrypted connections, some notion of who’s allowed in, protection from being hammered, sane security headers, consistent logging. The tempting mistake is to make each service handle those itself. Now you’ve got the same cross-cutting concerns implemented five times, five slightly different ways, five places to get it subtly wrong. The better shape is to do that work once, at the edge — a reverse proxy or gateway in front of everything — and let every backend inherit it. The edge is your policy layer. Use it.
Cross-cutting concerns are exactly the ones to centralize
The concerns worth pulling to the edge are the ones that aren’t specific to any one app — they apply to all of them, which is precisely why duplicating them per-service is waste and risk:
- TLS termination. Handle certificates and encryption in one place instead of teaching every service to do TLS. One cert story, one place to renew, one place to get the ciphers right.
- Authentication and access. A single gate deciding who gets in beats each backend inventing its own half-measure — and it means an unauthenticated service can’t accidentally end up exposed because it forgot the check.
- Rate limiting. Protect everything behind the edge from abuse and overload at the boundary, rather than hoping each service defends itself.
- Security headers and consistent logging. Set them uniformly so you don’t have one app with a solid header policy next to one with none, and so your access logs have a single shape.
The work every service shares is the work no service should own. Do it once at the door, or do it wrong in a dozen places.
The edge can also protect you from your upstreams
A reverse proxy isn’t only a front door for clients; it’s also a controlled client to your backends, and that’s a lever people underuse. It can validate an upstream’s certificate before trusting it, normalize quirks, and present a clean, stable face to callers while the mess lives behind it. I’ve put a proxy in front of a fiddly backend specifically so that clients talked to a sane, verified endpoint and never had to care about the backend’s certificate weirdness. The edge became the place where “is this upstream who it claims to be?” got answered once, correctly, for everyone.
That’s the same instinct as putting a gateway in front of your LLMs: a controlled choke point where you enforce policy, add observability, and contain the chaos, so the things behind it can stay simple.
Keep the edge’s rules as data, not a pile of special cases
The failure mode of a powerful edge is that it becomes a tangle — a giant, hand-edited config full of one-off exceptions nobody dares touch. The discipline that keeps it maintainable is treating the routing and policy as data: declarative, reviewable, version-controlled rules, not imperative cleverness bolted on request by request. That’s the whole argument in routing rules are data, not code — a proxy config is infrastructure, and it stays sane when it reads like a table of decisions instead of a script of hacks.
The edge relocates concerns; it can’t rewrite an app’s assumptions
Here’s the honest boundary, because centralizing at the edge is powerful enough to get overused. A proxy can add, enforce, and terminate cross-cutting concerns — but it can’t talk an application out of assumptions baked into it. The classic wall is an app that believes it owns the web root: no amount of edge rewriting reliably relocates a static site or single-page app that hardcoded its base URL at build time. That’s a real limit I’ve hit, and it’s its own post — a reverse proxy can’t fix an app that assumes it owns the root. The edge is the right home for shared concerns; it is not a place to fix an app’s internal worldview from the outside.
Ask “who should own this?” at the boundary
So when I add a service now, the question isn’t just “how do I route to it?” It’s “which of this service’s concerns are actually everyone’s concerns, and belong at the edge?” TLS, auth, rate limits, headers, upstream trust — pull those to the door and every backend gets them for free and gets them consistently. Leave the app-specific logic in the app. The result is fewer places to secure, one place to fix a cross-cutting bug, and backends that get to be simple because the boundary is doing the shared work. It’s a running theme in my private cloud and homelab work: the front door is where a lot of the leverage lives. If you’ve consolidated cross-cutting concerns at your edge and it paid off, I’d love to compare setups.