11 KiB
11 KiB
Architecture
System Overview
The SecNex API Gateway follows a modular architecture with clear separation of concerns. The system is built using the chi/v5 HTTP router and implements a middleware pipeline pattern.
┌────────────────────────────────────────────────────────────┐
│ Client Request │
└─────────────────────────┬──────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────┐
│ Gateway (chi Router) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Global Middleware Pipeline │ │
│ │ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │ │
│ │ │ Request ID │→ │ Real IP │→ │ Logger │ │ │
│ │ └────────────┘ └────────────┘ └──────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────┬──────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────┐
│ Route Handler │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Per-Route Middleware Chain │ │
│ │ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │ │
│ │ │ Auth │→ │ Strip │→ │ Reverse │ │ │
│ │ │ Middleware │ │ Prefix │ │ Proxy │ │ │
│ │ └────────────┘ └────────────┘ └──────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────┬──────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────┐
│ Reverse Proxy (httputil.ReverseProxy) │
│ │ │
│ ▼ │
│ Backend Service │
└────────────────────────────────────────────────────────────┘
Component Architecture
Directory Structure
app/
├── main.go # Application entry point
├── config/ # Configuration management
│ ├── config.go # Config interface
│ ├── file.go # File-based config loader
│ └── database.go # Database configuration
├── server/ # Core server components
│ ├── gateway.go # Main gateway server
│ ├── routes.go # Route registration & middleware chain
│ ├── api.go # API definitions
│ ├── host.go # Host definitions
│ └── target.go # Target (backend) definitions
├── middlewares/ # HTTP middleware
│ ├── auth.go # Authentication middleware
│ ├── host.go # Host logging middleware
│ └── logger.go # Structured logging middleware
└── utils/ # Utility functions
Core Components
Gateway (server/gateway.go)
The Gateway is the main server component that:
- Initializes the chi router
- Applies global middleware (request_id, real_ip, logger, host)
- Configures proxy directors for each API
- Registers route handlers
- Starts the HTTP server
Routes (server/routes.go)
The Routes component handles:
- Creating route handlers from configuration
- Applying per-route middleware chain (Auth → StripPrefix)
- Registering routes with chi router (method-agnostic)
- Connecting routes to API backends
API (server/api.go)
API definitions that:
- Link hosts to backend targets
- Implement
http.Handlerinterface for proxying - Delegate requests to the reverse proxy
Hosts (server/host.go)
Host definitions for:
- Virtual hosting support
- Domain-based routing
- Host header validation
Targets (server/target.go)
Target (backend) definitions that:
- Store backend service URLs
- Create
httputil.NewSingleHostReverseProxyinstances - Handle proxy configuration
Auth Middleware (middlewares/auth.go)
Authentication middleware that:
- Validates presence of configured auth header (e.g.,
X-Api-Key,Authorization) - Supports path-based filtering via include/exclude patterns
- Removes auth header before forwarding to backend
- Provides extensive DEBUG logging for troubleshooting
Middleware Chain
Global Middleware
Applied to all requests via chi middleware:
| Feature | Description |
|---|---|
request_id |
Adds unique request ID to context |
real_ip |
Determines the real client IP from headers |
logger |
Logs HTTP requests with structured JSON output |
host |
Logs the host header for each request |
Per-Route Middleware
Applied in order to each route handler:
- Auth (if enabled) - Validates authentication header with path filtering
- StripPrefix (if enabled) - Removes specified prefix from request path before proxying
Request Flow
- Client Request → Gateway receives HTTP request
- Global Middleware → Request ID, Real IP, Host logging, Logger applied
- Route Matching → Chi matches route pattern (e.g.,
/api/v1/*) - Per-Route Middleware → Auth → StripPrefix (if enabled)
- Reverse Proxy → Request forwarded to backend API
- Response → Backend response returned to client
Authentication Flow
The authentication middleware supports flexible path-based filtering:
┌─────────────────────────────────────┐
│ Include and Exclude both empty? │
└──────────────────┬──────────────────┘
│ Yes
┌─────────┴─────────┐
│ Auth required │
│ for ALL paths │
└───────────────────┘
│ No
┌─────────┴─────────┐
▼ │
┌───────────────────┐ │
│ Only Include set? │ │
└─────────┬─────────┘ │
│ Yes │ No │
▼ ▼ │
┌────────┐ ┌────────────────┐│
│ Auth │ │ Exclude set? ││
│ ONLY │ └───────┬────────┘│
│ for │ │ No │
│ Include│ ┌────┴────┐ │
│ paths │ │ Auth │ │
└────────┘ │ for ALL │ │
└────┬────┘ │
│ Yes │
┌─────────┴─────────┐│
│ Auth EXCEPT ││
│ matching Exclude ││
└───────────────────┘│
│
▼
Check Auth Header
Path Filtering Logic:
- Both include and exclude empty → Auth required for ALL paths
- Only include set → Auth required ONLY for paths matching include patterns
- Only exclude set → Auth required for ALL paths EXCEPT those matching exclude patterns
- Both set → Include takes precedence (same as #2)
Wildcard Pattern Matching:
*matches any path/api/*matches/api/and any subpath/api/v1/public/test/*matches the prefix and any subpath
Configuration Flow
- Load
gateway.yamlviaconfig.NewFile() - Parse YAML into
Configurationstruct - Create Hosts from configuration
- Create Targets from configuration
- Create APIs (linking Hosts to Targets)
- Create Routes (linking Routes to APIs with Auth config)
- Initialize Gateway with all components
- Configure proxy directors
- Register routes with chi router (including Auth middleware)
- Start HTTP server
Logging
The gateway uses structured JSON logging via masterlog:
- HTTP Request Logging - method, path, status, duration, host, IP
- Gateway Events - startup, route registration, proxy configuration
- Auth Debug Logs - detailed auth decision logging when DEBUG level enabled
- Sensitive Field Pseudonymization - user_id, email, ip fields are pseudonymized
Example log output:
{
"level": "info",
"msg": "HTTP Request",
"method": "GET",
"path": "/api/v1/users",
"status": 200,
"duration": "45ms",
"host": "localhost:8080",
"ip": "127.0.0.1:52342"
}
Auth debug logs (when DEBUG level enabled):
{
"level": "debug",
"msg": "AuthMiddleware: Checking if path requires auth",
"path": "/api/v1/users",
"requires_auth": true,
"include": [],
"exclude": ["/api/v1/public/*"]
}