docs: update architecture, security and contributing docs for gzip and font subsetting

This commit is contained in:
2026-04-08 22:32:51 +02:00
parent 8a10981ecc
commit ce36939d31
4 changed files with 16 additions and 2 deletions

3
.gitignore vendored
View File

@@ -24,6 +24,9 @@ vendor/
# AI workspace
.ki-workspace/
# Python (tools/subset-icons.py)
.venv/
# OS
.DS_Store
Thumbs.db

View File

@@ -36,7 +36,7 @@ internal/
logging/ ← Structured logging with levels
mail/ ← SMTP email service (notifications, invitations)
models/ ← Data models (User, SSHKey, Server, etc.)
security/ ← CSRF, security headers, rate limiting, proxy detection
security/ ← CSRF, security headers, rate limiting, gzip compression, proxy detection
servers/ ← Server and server group management, access assignments
sshutil/ ← SSH key generation (RSA, Ed25519, Ed448)
updater/ ← Background update checker (Gitea releases API)
@@ -59,7 +59,7 @@ web/
8. **Configure security** subsystem (trusted proxy parsing)
9. **Set up HTTP routes** and load templates
10. **Start session cleanup** goroutine (removes expired sessions every minute)
11. **Apply middleware chain**: request logger → security headers → rate limiting → size limiting → CSRF
11. **Apply middleware chain**: request logger → security headers → rate limiting → size limiting → CSRF → gzip compression
12. **Start cron scheduler** (checks for pending jobs every 30 seconds)
13. **Start key enforcement worker** (if enabled in Admin Settings)
14. **Start HTTP server**
@@ -95,6 +95,7 @@ Client → [Nginx/Caddy] → Keywarden HTTP Server
├── Rate Limit Middleware (login endpoints)
├── Size Limit Middleware
├── CSRF Middleware (double-submit cookie)
├── Gzip Compression Middleware
├── Public Routes (/login, /invite/*)
├── Auth Routes (requireAuth → all authenticated users)

View File

@@ -82,6 +82,7 @@ keywarden/
│ │ ├── csrf.go # CSRF double-submit cookie middleware
│ │ ├── headers.go # Security headers middleware (CSP, X-Frame-Options, etc.)
│ │ ├── proxy.go # Trusted proxy IP extraction
│ │ ├── gzip.go # Gzip compression middleware
│ │ ├── ratelimit.go # IP-based rate limiting middleware
│ │ └── sizelimit.go # Request body size limit middleware
│ ├── servers/servers.go # Server and group management, access assignments
@@ -91,6 +92,9 @@ keywarden/
│ ├── embed.go # Go embed directives
│ ├── static/ # CSS, JS, fonts (Tabler UI)
│ └── templates/ # HTML templates
├── tools/
│ ├── subset-icons.py # Tabler Icons font/CSS subset tool
│ └── tabler-icons-full/ # Full Tabler Icons source files
├── docs/ # Documentation
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Docker Compose configuration

View File

@@ -141,6 +141,12 @@ Login endpoints (`POST /login`, `POST /login/mfa`) are rate-limited per IP addre
A background goroutine cleans up expired rate limit entries every 5 minutes.
## Gzip Compression
HTTP responses are compressed using gzip for clients that send `Accept-Encoding: gzip`. Only compressible content types are compressed (HTML, CSS, JS, JSON, SVG). Already-compressed formats (woff2, images) are passed through unchanged.
The middleware uses a `sync.Pool` of gzip writers for efficient memory reuse.
## Request Size Limiting
Request bodies are limited to prevent denial-of-service via large uploads.