Blog post
I Don’t Expose APIs to the Internet.
(And You Probably Shouldn’t Either.)
I don’t use Traefik because it’s cool.
I use it because I don’t trust APIs.
Not even mine.
I need granular control.
Full visibility.
Zero trust for anything that touches my self-hosted network.
So Here’s the Rule I Swear By
No API in my lab talks directly to the internet.
Nada.
- Not “just for testing.”
- Not “just temporarily.”
- Not “only this one endpoint.”
Everything goes through a gateway.
My Setup (Simple. Strict. Non-Negotiable.)
- Cloudflare sits outside (edge policy + TLS).
- Cloudflare Tunnel reaches into my DMZ (no inbound WAN ports).
- Traefik lives in the DMZ and acts as the internal gatekeeper.
- Authentik handles identity (OIDC login + decisions).
- The backend API sits quietly in a private VLAN, invisible to the outside world.
No open inbound WAN ports.
No accidental exposure.
No “oops, forgot to close that.”
That’s the architecture.
What That Actually Looks Like
Cloudflare (Edge) → Authentik (Identity) → Traefik (Gatekeeper) → Backend API (Private VLAN)
The point is double enforcement: even if something upstream is misconfigured, Traefik still refuses unauthenticated requests.
Now, What Happens If You Skip the Gateway?
Let’s say I expose an API directly.
notify.rae-ayen.com — a REST API I host.
Now something must:
- Authenticate users correctly
- Authorize them correctly
- Enforce HTTPS properly
And if ruthless malicious actors show up?
- Survive brute-force attempts
- Survive replay attacks
- Survive automated flooding
- Detect, log, and react to abuse
That’s a lot to ask from a lightweight service.
In my case, I deliberately deployed a backend API without native authentication or native rate limiting.
Not because I forgot.
Because security belongs at the gateway.
If I exposed that backend directly:
- Anyone could hit it.
- Anyone could try to overwhelm it.
- Anyone could “stress test” it from their bedroom.
There would be no choke point.
And that’s dangerous. (Also dangerous for my wallet.)
What the Gateway Actually Does
1) It Forces Identity
If you hit notify.rae-ayen.com and you can’t authenticate, you don’t reach the backend.
You get redirected.
Proof: blocked before backend routing
Proof: identity flow (OIDC) is enforced
Proof: client-side evidence (redirected to OIDC, not backend)
Double enforcement. Ace.
No anonymous probing.
No “let me just try this endpoint.”
No guessing.
Prove who you are first. Then we talk.
2) It Enforces HTTPS Automatically
Everything is HTTPS.
Try HTTP?
Proof: HTTP → HTTPS redirect
- No plaintext tokens
- No downgrade attacks
- No accidental leaks
The backend doesn’t need to think about transport security.
The gateway handles it.
3) It Rate Limits — And That’s Security
Rate limiting is not performance tuning. It’s abuse control.
When I replay authenticated requests repeatedly (the exact thing automation does), the gateway responds with a rate-limit error.
Proof: endpoint used to validate rate limiting
Proof: throttled at the gateway (not the backend)
- The backend never sees the flood.
- Automation gets throttled.
- Abuse loses scale.
So, Homelabbers — Why Are Gateways Not Optional?
Without a gateway, every security decision lives inside the application.
That’s fragile. It’s irresponsible.
APIs are not front doors.
They’re service entrances.
If you leave them open, someone will walk in.
Traefik, in my setup, isn’t a feature.
It’s a bouncer.
And I like my bouncers strict.