LAB-001Web & APIComplete

API Gateway Security Lab

Multi-layered API security architecture on a self-hosted Proxmox hypervisor: API gateway, WAF, identity provider, and observability stack covering the full chain from request ingestion to threat detection.

Detection: Coraza WAF + Grafana

Designed and deployed a production-grade API security stack from scratch: API Gateway, WAF, identity provider, and observability, to simulate real-world API threat scenarios.

Overview

Built a multi-layered API security architecture on a self-hosted Proxmox hypervisor, combining open-source tools used in enterprise environments. The lab covers the full security chain: from request ingestion to threat detection, authentication enforcement, and traffic monitoring.

Architecture

  • APISIX 3.15 as the API Gateway (routing, plugin orchestration)
  • Coraza WAF (WASM) for real-time request inspection, blocks SQLi, XSS, and malformed payloads
  • Keycloak 24 as the Identity Provider (OAuth2/OIDC with RS256 JWT issuance)
  • Prometheus + Grafana for metrics collection and security dashboards
  • httpbin as the backend target

Security layers implemented

  • WAF: Coraza inspects every inbound request against custom rulesets before it reaches the backend
  • Authentication: APISIX validates JWTs via JWKS endpoint; unsigned or expired tokens are rejected at the gateway
  • Rate limiting: 5 requests per 60 seconds per IP; returns HTTP 429 on breach
  • Proxy rewrite: internal routing decoupled from external paths

Key technical decisions

  • Coraza deployed as a WASM plugin (not a sidecar). Rules are injected inline via API because the WASM sandbox has no filesystem access
  • Keycloak frontend URL explicitly set to fix JWT issuer mismatch between internal Docker DNS and external validation
  • Prometheus metrics exposed on a dedicated port (9091) to avoid exposing the admin API

What this demonstrates

Ability to design, deploy, and troubleshoot a layered API security stack. Not just configure tools, but understand why each component is positioned where it is, and what breaks if it isn't.