# Auth-proxy Security Model ## Authentication flow 1. Client request arrives at NGINX. 2. NGINX sends an internal auth_request subrequest to auth-proxy. 3. Auth-proxy checks: - Is the IP in the permanent whitelist? → Allow. - Is the IP in the temporary whitelist and not expired? → Allow. - Otherwise → 401 Unauthorized. 4. NGINX passes the request to the upstream service if auth-proxy returned 200. 5. NGINX returns 401 to the client if auth-proxy returned 401/403. ## IP handling ### Permanent whitelist - Stored in SQLite `permanent_whitelist` table. - Only single IPs and CIDR ranges (as strings) are supported. - Added/removed via the `/api/whitelist/perm` API. ### Temporary whitelist - Stored in SQLite `temp_whitelist` table. - Entries expire after their TTL. - The cleanup goroutine runs every 60 seconds (configurable) to remove expired entries. ## API key The API key is the only secret for the /api/* endpoints. It's sent as a bearer token in the Authorization header. - **Required.** The service will not start without it. - Keep it secret. Don't log it. Don't put it in the URL. - Use a strong random string. - Rotate it regularly. ## Audit log All whitelist operations are logged to the `audit_log` table in SQLite. Each entry records: - `action` — what happened (`add_temp`, `delete_temp`, `add_perm`, `delete_perm`, `expire_temp`) - `ip` — the affected IP or CIDR range - `ttl_seconds` — for temp entries - `reason` — the reason provided - `api_client_ip` — the IP that made the API call (from NGINX `X-Real-IP`) Retrieve logs via the `/api/logs` endpoint. The audit log is automatically rotated to maintain a maximum of 200,000 entries. ## IP validation The `/api/whitelist/temp` and `/api/whitelist/perm` endpoints validate inputs: - `/api/whitelist/temp` requires a valid IP address. - `/api/whitelist/perm` requires a valid IP address or CIDR range. - Invalid inputs return `400 Bad Request`. ## Graceful shutdown The service listens for SIGTERM and SIGINT. On signal: 1. Stop accepting new connections. 2. Close idle connections. 3. Wait for in-flight requests to complete (up to 30 seconds). 4. Exit. This ensures Docker deployments can shut down cleanly. ## What we don't do - We don't support JWT/OAuth. If you need these, add them later. - We don't support session state. The auth decision is made per-request. - We don't support rate limiting. Use NGINX's limit_req for that. - We don't support IP-based rate limiting. Use NGINX's limit_conn for that. - We support IPv6. The `/api/whitelist` endpoints accept both IPv4 and IPv6 addresses. - We don't support TLS. The auth endpoint should always be served over TLS. - We don't support logging to a file. Logs go to stdout (Docker). - We don't support metrics. If you need metrics, add them later. - We don't support health checks with Prometheus. The /status endpoint returns a JSON response with uptime, DB status, and whitelist counts. - We don't support configuration via a config file. Use environment variables. - We don't support multiple domains. The auth-proxy service doesn't care about domains. - We don't support HTTP/2. The auth-proxy service uses HTTP/1.1 only. - We don't support WebSocket. The auth-proxy service doesn't need WebSocket. - We don't support gRPC. The auth-proxy service is a simple REST API.