Lots more changes

This commit is contained in:
2026-06-01 01:29:47 -05:00
parent 8bec7f0dda
commit 050ec138f3
20 changed files with 1773 additions and 689 deletions
+39 -14
View File
@@ -2,17 +2,20 @@
Scratchbox is a minimal self-hosted scratch service written in Go. It is intentionally unauthenticated and optimized for temporary sharing of text or small files with an expiration time.
Each upload creates exactly one scratch. For multi-file sharing, bundle files into an archive (for example `.zip` or `.tar.gz`) and upload that single archive file.
Scratch content is stored on disk gzip-compressed transparently to reduce filesystem usage; API/UI reads return original uncompressed content.
For multi-file sharing, bundle files into an archive (for example `.zip` or `.tar.gz`) before upload.
Scratch content is gzip-compressed and AES-encrypted on disk transparently; API/UI reads return original uncompressed content.
## Quick Start
1. Generate defaults directly:
- `go run ./cmd/scratchbox generate-config > config.yaml`
2. Adjust settings for your environment.
3. Start the server:
2. Generate an encryption key file next to the config:
- `go run ./cmd/scratchbox generate-key > config.key`
- or: `openssl rand -base64 32 > config.key`
3. Adjust settings for your environment.
4. Start the server:
- `go run ./cmd/scratchbox server --config config.yaml`
4. Open:
5. Open:
- `http://127.0.0.1:8080/`
Without `--config`, built-in defaults are used.
@@ -43,6 +46,16 @@ All configuration is YAML.
- `max_header_bytes`: max HTTP header size in bytes.
- Must be `> 0`
- Default: `1048576` (1 MiB)
- `access_log`: structured request logs.
- `enabled`: enable HTTP access logs
- Default: `true`
- `file_path`: optional log file path
- When set, logs are tee'd to both stdout and the file
- `max_size`: rotation threshold for `file_path`
- Supported units: `B`, `KB`, `MB`, `GB`, `KiB`, `MiB`, `GiB`
- Default: `100MiB`
- `max_backups`: number of rotated files to retain
- Default: `5`
### `limits`
@@ -53,7 +66,7 @@ All configuration is YAML.
- Default: `100MiB`
- `default_ttl`: expiration applied to new scratches.
- Must be `> 0` and `<= 24h`
- Default: `1h`
- Default: `15m`
- `raw_cache_max_size`: max total decompressed bytes cached in memory for `/api/raw` range requests.
- Supported units: `B`, `KB`, `MB`, `GB`, `KiB`, `MiB`, `GiB` (case-insensitive)
- Must be `> 0`
@@ -70,6 +83,12 @@ All configuration is YAML.
- `cleanup_interval`: background interval for deleting expired content.
- Must be at least `10s`
- Default: `1m`
- `encryption_key_file`: path to a file containing a base64-encoded 32-byte key used for at-rest encryption.
- Relative paths are resolved from the config file directory
- Default: `config.key` (expected alongside `config.yaml`)
- Keep this key stable across restarts
- Changing the key makes existing scratch files unreadable
- `generate-key` emits a fresh random key each run
### `security`
@@ -84,14 +103,18 @@ All configuration is YAML.
- `trusted_proxy_ips`: list of reverse-proxy IPs/CIDRs permitted to supply forwarded headers.
- Required when `trust_proxy_headers: true`
- Examples: `127.0.0.1`, `10.0.0.0/8`
- `rate_limit.enabled`: enable per-IP token-bucket rate limiting on write and scratch-read routes (`POST /api/scratch`, `GET /api/scratch/{id}`, `GET /s/{id}`, `GET /api/raw/{id}`).
- Default: `true`
- `rate_limit.requests_per_minute`: steady refill rate per client IP.
- Must be `> 0`
- Default: `30`
- `rate_limit.burst`: immediate burst capacity per client IP.
- Must be `> 0`
- Default: `10`
- `rate_limit_ui`: per-IP token-bucket for UI routes (`GET /`, `GET /u`, `GET /s/{id}`).
- `enabled` default: `false`
- `requests_per_minute` must be `> 0` (default `360`)
- `burst` must be `> 0` (default `120`)
- `rate_limit_api_read`: per-IP token-bucket for API read routes (`GET /api/config`, `GET /api/scratch/{id}`, `GET /api/raw/{id}`).
- `enabled` default: `false`
- `requests_per_minute` must be `> 0` (default `300`)
- `burst` must be `> 0` (default `100`)
- `rate_limit_api_write`: per-IP token-bucket for API write route (`POST /api/scratch`).
- `enabled` default: `true`
- `requests_per_minute` must be `> 0` (default `30`)
- `burst` must be `> 0` (default `10`)
## Security Posture
@@ -129,3 +152,5 @@ Scratchbox storage is designed for a single process instance per `storage.data_d
- Do not run multiple scratchbox processes against the same data directory.
- Metadata/index writes are process-local and are not coordinated with cross-process locking.
- Scratch payload files and metadata index are encrypted at rest.
- Scratch IDs are derived from the SHA-256 of the stored blob (encrypted+gzip payload on disk).