Blog post

I Don’t Expose APIs to the Internet.

(And You Probably Shouldn’t Either.)

⏱️ 5–7 min read Topic: API Gateway Security

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
Cloudflare blocks unauthenticated access before the request reaches backend services
Cloudflare stops unauthenticated traffic at the edge.
Proof: identity flow (OIDC) is enforced
Cloudflare Access integrated with Authentik for OIDC authentication
Identity first: Cloudflare Access + Authentik (OIDC).
Proof: client-side evidence (redirected to OIDC, not backend)
Burp shows a 302 redirect into Authentik OIDC authorize flow
From the client perspective: redirected into OIDC, not into the 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
HTTP request redirected to HTTPS
HTTP is redirected to HTTPS automatically.
  • 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
Test endpoint used for rate-limit validation
Controlled test target for rate-limiting validation.
Proof: throttled at the gateway (not the backend)
Gateway rate-limit response returned to the client
Excessive requests are throttled at the gateway before the backend sees them.
  • 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.

Do You Have Bouncers?