Update project structure to use a src/ directory layout and improve documentation across multiple files. - Update README.md build command to use ./src - Add directory structure documentation - Update status endpoint to include DB health status - Add pagination support (limit/offset) to whitelist list endpoints - Document new query parameters with examples - Update deployment guide to mark API token as required - Add testing instructions - Clarify audit log rotation in design documentation
122 lines
2.7 KiB
Markdown
122 lines
2.7 KiB
Markdown
# Design Decisions
|
|
|
|
## Why Go?
|
|
|
|
- Single binary — no external dependencies.
|
|
- Small memory footprint — ~10 MB for a typical deployment.
|
|
- Fast startup — < 1 second.
|
|
- Simple to compile and distribute.
|
|
|
|
## Why not NGINX auth_basic?
|
|
|
|
NGINX's auth_basic is simpler but doesn't support:
|
|
|
|
- IP whitelisting (you'd need the geo module or a third-party module).
|
|
- Temporary whitelisting (requires config reload).
|
|
- API-based management.
|
|
|
|
Our auth-proxy service fills these gaps while keeping the architecture simple.
|
|
|
|
## Why not Authelia?
|
|
|
|
Authelia is a full-featured self-hosted auth portal with:
|
|
|
|
- SSO integration
|
|
- 2FA
|
|
- MFA
|
|
- LDAP
|
|
- OIDC
|
|
|
|
But for our use case:
|
|
|
|
- It's heavier (requires Postgres, Redis, etc.).
|
|
- It doesn't support temporary whitelisting out of the box.
|
|
- It requires a login portal.
|
|
|
|
We wanted something simpler.
|
|
|
|
## Why not Authentik?
|
|
|
|
Authentik is a full-featured identity provider with:
|
|
|
|
- SSO
|
|
- MFA
|
|
- OIDC
|
|
- LDAP
|
|
- SCIM
|
|
|
|
But it's too heavy for our use case. We just need IP whitelisting + Basic Auth.
|
|
|
|
## Why not Pomerium?
|
|
|
|
Pomerium is a zero-trust proxy with:
|
|
|
|
- OIDC
|
|
- MFA
|
|
- IP-based access control
|
|
- Policy engine
|
|
|
|
But it's overkill for our use case. We just need IP whitelisting + Basic Auth.
|
|
|
|
## Why not oauth2-proxy?
|
|
|
|
oauth2-proxy is a reverse proxy with:
|
|
|
|
- OIDC
|
|
- SSO
|
|
- MFA
|
|
|
|
But it's designed for OIDC, not for IP whitelisting.
|
|
|
|
## Why not a custom script?
|
|
|
|
A shell script would work but:
|
|
|
|
- No type safety.
|
|
- No built-in HTTP server (need to use Python/Node).
|
|
- No standard library (need to install packages).
|
|
- No built-in JSON encoding/decoding.
|
|
|
|
Go's standard library is sufficient for our needs.
|
|
|
|
## Why SQLite?
|
|
|
|
SQLite provides:
|
|
|
|
- Single file — no external dependencies.
|
|
- Persistence across restarts.
|
|
- ACID transactions.
|
|
- Simple WAL mode for concurrent reads.
|
|
|
|
For a handful of IPs (dozens at most), SQLite is:
|
|
|
|
- Simple to deploy.
|
|
- Fast (single-file, no network).
|
|
- No external dependencies.
|
|
|
|
## Why in-memory temporary whitelist?
|
|
|
|
For a handful of IPs (dozens at most), an in-memory map is:
|
|
|
|
- Simple to implement.
|
|
- Fast (O(1) lookup).
|
|
- No external dependencies.
|
|
|
|
If you need persistence across restarts, add a disk-backed store later.
|
|
|
|
## Why a background cleanup goroutine?
|
|
|
|
The cleanup goroutine removes expired temporary entries and rotates the audit log.
|
|
It runs every 60 seconds (configurable). The audit log rotation keeps the database
|
|
from growing indefinitely — it maintains a maximum of 100,000 entries.
|
|
|
|
## Why poll instead of inotify?
|
|
|
|
Polling is simpler and works inside Docker containers where inotify
|
|
may not be available (no host filesystem access).
|
|
|
|
## Why not use Redis?
|
|
|
|
For our use case, Redis is overkill.
|
|
We chose an in-memory map + periodic cleanup.
|