Heavy security and file splitting
CI / Go Tests (push) Successful in 15s
CI / Build (push) Successful in 9s
Format / gofmt (push) Successful in 7s
Release Artifacts / Validate release tag (push) Successful in 2s
Release Artifacts / Build and release executables (push) Successful in 15s
Release Artifacts / Build and release Docker image (push) Successful in 28s

This commit is contained in:
2026-06-01 20:15:28 -05:00
parent bdbe1a9416
commit ad4355df17
27 changed files with 1540 additions and 1166 deletions
+17 -1
View File
@@ -64,13 +64,14 @@ Storage encryption key behavior:
- On subsequent startups, Scratchbox reuses the same key file from that data directory.
- Keep `storage.data_dir` persistent; losing or replacing `metadata.key` makes existing scratches unreadable.
Environment variables supported by `scratchbox server --env`:
Environment variables supported by `scratchbox server --env` (note: when `--env` is used, the variables and their values are printed to stdout on startup for diagnostics, with values of IP allow/trusted lists redacted):
- `SCRATCHBOX_SERVER_LISTEN_ADDR`
- `SCRATCHBOX_SERVER_READ_HEADER_TIMEOUT`
- `SCRATCHBOX_SERVER_READ_TIMEOUT`
- `SCRATCHBOX_SERVER_WRITE_TIMEOUT`
- `SCRATCHBOX_SERVER_IDLE_TIMEOUT`
- `SCRATCHBOX_SERVER_SHUTDOWN_TIMEOUT`
- `SCRATCHBOX_SERVER_MAX_HEADER_BYTES`
- `SCRATCHBOX_SERVER_ACCESS_LOG_ENABLED`
- `SCRATCHBOX_SERVER_ACCESS_LOG_FILE_PATH` (forced empty by Docker image)
@@ -94,6 +95,7 @@ Environment variables supported by `scratchbox server --env`:
- `SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_ENABLED`
- `SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_REQUESTS_PER_MINUTE`
- `SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_BURST`
- `SCRATCHBOX_SECURITY_HSTS_ENABLED`
Example `.env` for Docker:
@@ -104,6 +106,7 @@ SCRATCHBOX_SERVER_READ_HEADER_TIMEOUT=5s
SCRATCHBOX_SERVER_READ_TIMEOUT=30s
SCRATCHBOX_SERVER_WRITE_TIMEOUT=30s
SCRATCHBOX_SERVER_IDLE_TIMEOUT=120s
SCRATCHBOX_SERVER_SHUTDOWN_TIMEOUT=10s
SCRATCHBOX_SERVER_MAX_HEADER_BYTES=1048576
SCRATCHBOX_SERVER_ACCESS_LOG_ENABLED=true
@@ -130,6 +133,7 @@ SCRATCHBOX_SECURITY_RATE_LIMIT_API_READ_BURST=100
SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_ENABLED=true
SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_REQUESTS_PER_MINUTE=30
SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_BURST=10
SCRATCHBOX_SECURITY_HSTS_ENABLED=true
```
## Release Artifacts
@@ -185,6 +189,9 @@ All configuration is YAML.
- `idle_timeout`: maximum keep-alive idle time between requests.
- Must be `> 0`
- Default: `120s`
- `shutdown_timeout`: graceful shutdown timeout for in-flight requests on SIGTERM/INT.
- Must be `> 0`
- Default: `10s`
- `max_header_bytes`: max HTTP header size in bytes.
- Must be `> 0`
- Default: `1048576` (1 MiB)
@@ -243,6 +250,7 @@ All configuration is YAML.
- Keep `false` unless behind a trusted reverse proxy that sets these headers.
- `trusted_proxy_ips`: list of reverse-proxy IPs/CIDRs permitted to supply forwarded headers.
- Required when `trust_proxy_headers: true`
- **Must be the *immediate* reverse proxies only (e.g. the nginx/caddy in front of this service); never use 0.0.0.0/0 or broad ranges unless you fully control the entire path.**
- Examples: `127.0.0.1`, `10.0.0.0/8`
- `rate_limit_ui`: per-IP token-bucket for UI routes (`GET /`, `GET /u`, `GET /s/{id}`).
- `enabled` default: `false`
@@ -256,6 +264,7 @@ All configuration is YAML.
- `enabled` default: `true`
- `requests_per_minute` must be `> 0` (default `30`)
- `burst` must be `> 0` (default `10`)
- `hsts_enabled`: enable HSTS header (default: `true`; for public proxy TLS setups; set `false` for local HTTP-only per LAN notes).
## Security Posture
@@ -295,3 +304,10 @@ Scratchbox storage is designed for a single process instance per `storage.data_d
- Metadata/index writes are process-local and are not coordinated with cross-process locking.
- Scratch payload files and metadata index are encrypted at rest.
- Public scratch IDs are short random aliases; stored blobs still use SHA-256-derived internal blob IDs on disk.
Operational internals (not tunable; see source consts):
- Public IDs: 12 alphanum chars (crypto/rand), up to 8 attempts to reserve unique.
- Encrypted chunks: 64 KiB plaintext (SBX1 magic + per-chunk nonce prefix+counter for AES-256-GCM).
- Index: full random nonce per persist (SMD1).
- Background expiry + startup reconcile walk the in-memory map under exclusive lock (plus optional persist); practical cardinality limited by default 15m TTL + 100MiB uploads (low hundreds of live entries expected).
- Raw /api/raw cache: small LRU (default 32 entries, total bytes cap) with coalescing; serves decompressed content.