elfatih.net infrastructure · api.elfatih.net · originally 2026-07-20 · updated 2026-07-22
API Gateway Deployment Plan // APISIX
VPS · Caddy edge · Authelia SSO · Public internet · Browser users
Status — 2026-07-22: This was the original proposal. Phase 1 is now done and live in production — real containers, real TLS, real bugs found and fixed along the way. This page is kept as-is for the original reasoning and phase template; for what was actually built (and where it diverged from this plan), see the Implementation Guide and the Testing & Deployment Guide.
Tool Recommendation: APISIX
Reason
Detail
Dashboard UI
Built-in APISIX Dashboard — covers the UI requirement
Authelia integration
Native OIDC via openid-connect plugin
Lightweight
Runs well on a single VPS, less overhead than Kong DB mode
Greenfield fit
Declarative config + Admin API — easy to automate
Coraza WAF
Official APISIX plugin — drops in when you're ready
Wazuh
Consume APISIX JSON logs via filebeat — zero redesign
APISIX Admin API :9180 — 127.0.0.1 ONLY, never routed
Critical: APISIX Admin API must never be routed through Caddy. It has no auth by default. One misconfigured Caddy block exposes full gateway control to the internet. Access only via SSH tunnel if needed remotely.
Auth Flow — End User
1. Browser → api.elfatih.net/some-endpoint
2. Caddy receives, passes to APISIX
3. APISIX openid-connect plugin checks for valid session / Bearer token
4. No valid session → redirect to Authelia login page
5. User authenticates at Authelia (MFA if configured)
6. Authelia issues OIDC token, redirects back to api.elfatih.net
7. APISIX validates token, extracts identity (sub, email, roles)
8. Request forwarded to upstream with X-User headers injected
9. Upstream trusts headers — does NOT re-authenticate
Dashboard Access Flow
1. Browser → dashboard.elfatih.net
2. Caddy forward-auth check → Authelia
3. Not authenticated → Authelia login
4. Authenticated → Caddy proxies to APISIX Dashboard :9000
5. Dashboard has its own login — change default credentials immediately
Two auth layers: Authelia stops internet noise. Dashboard login stops lateral movement if Authelia is ever bypassed.
Data Store: etcd
Single etcd node — no clustering on single VPS
etcd down → APISIX loses config reload, but cached routes keep serving
etcd port :2379 — localhost only, never exposed
etcd data = your gateway config — back it up before go-live
Phase Plan
PHASE 1Foundation — Day 1–2✓ Done — Live in production
Goal: APISIX running, dashboard accessible, integrated with Caddy.
Deploy APISIX via Docker Compose (apisix + etcd + apisix-dashboard)
Verify Admin API NOT exposed publicly (127.0.0.1 only)
Test route to placeholder upstream (httpbin) — confirm end-to-end TLS
Deliverable: APISIX live, dashboard behind Authelia, test route responding. Achieved — also grew to include a fourth vhost (learn.elfatih.net), a git repo, and a 25-test automated suite not in the original scope. Details in the guides linked above.
PHASE 2Auth Layer — Day 3→ Next
Goal: End users authenticate via Authelia before hitting any route.
Enable APISIX openid-connect plugin
Configure against Authelia OIDC (client_id, client_secret, discovery endpoint)
Apply plugin globally — all routes protected by default
Whitelist public routes (health checks, etc.)
Test full OIDC redirect flow end-to-end
Deliverable: No route reachable without a valid Authelia session.
PHASE 3Core Policies — Day 4–5
Goal: Production-grade policies before any real service is onboarded.
Policy
Config
Rate limiting
1000 req/min per IP globally, per-route override
Request transformation
Strip internal headers, add X-Request-ID
CORS
Global allowed origins, per-route override
Timeout
30s upstream default
Retry
2 retries on 502/503
Health checks
Passive, circuit breaker on 3 consecutive failures
Deliverable: Policy config documented and version-controlled in Git.
PHASE 4Observability — Day 6
Goal: Logs and metrics ready to feed Wazuh and Grafana when implemented.
Enable prometheus plugin → metrics endpoint for Grafana
Enable http-logger plugin → JSON access logs to local file