# Workflow * branch (from `main`) * do the work in Next Step * move Next Step to the top of Completed Steps * move the top item of Future Steps into Next Step * commit (`TODO.md` changes in the same commit as the work) * merge to `main` if the branch is not protected, otherwise open a PR * push # Status pre-1.0. No git tags exist. main (6b4a1d7, 2026-04-07) is current with origin; recent work extracted the internal/magic and internal/allowlist packages. The 10 gosec findings from the 2026-07-06 morning survey are NOT fixed on main: the newest gosec/lint fix commits are from 2026-02-25 (85729d9, ce6db76) and nothing since touches gosec, so those findings remain open. # Next Step Fix the 10 open gosec lint findings so make check passes on main again (main must always be green; no gosec fix commits have landed since 2026-02-25). No blanket suppressions; fix or justify each finding individually. # Completed Steps - 2026-04-07 extract magic byte detection into internal/magic (#42) - 2026-03-25 extract allowlist package from internal/imgcache (#41) - 2026-03-25 move schema_migrations table creation into 000.sql (#36) - 2026-03-20 enforce and document exact-match-only signature verification (#40) - 2026-03-20 bound imageprocessor.Process input read to prevent unbounded memory use (#37); consolidate appname into an internal/globals constant (#34) - 2026-03-18 parse version prefix from migration filenames (#33) - 2026-03-15 QA audit fixes for 1.0/MVP readiness (#25) - 2026-03-02 split Dockerfile with pre-built golangci-lint stage for faster CI (#23) - 2026-02-25 repo policy compliance: CI workflow, hash-pinned images, golangci-lint and gosec fixes of that date (#14); arm64 Docker build fix (#16) - 2026-01-08 WebP and AVIF encoding support via govips (both former P0 image processing items, now done) # Future Steps - P0: manual test pass of the auth and encrypted URL flows, then commit the checked-off results to TODO.md: visit / and see the login form; wrong key shows an error; correct signing key shows the generator form; a generated encrypted URL serves the image; an expired URL (short TTL) returns 410; logout redirects back to login - P0: implement cache size management and eviction so the disk cannot fill up - P0: validate configuration on startup, fail fast on bad config - P1: implement blocked networks configuration to extend SSRF protection - P1: rate limit global concurrent upstream fetches to prevent resource exhaustion - P1: strip EXIF and other metadata from processed images (privacy) - P2: security - referer blacklist - per-IP rate limiting - per-origin rate limiting - P2: HTTP response handling - Last-Modified headers - Vary header for content negotiation - X-Request-ID propagation - P2: auto format selection (format=auto based on Accept header) - P2: configuration - add all configuration options from README - environment variable overrides - YAML config file support - P2: operational - optional Sentry error reporting - comprehensive request logging - Prometheus performance metrics - integration tests for the image proxy flow - load tests to verify the 1k to 5k req/s target - P2: documentation - configuration options - API endpoints - deployment guide - example nginx or caddy reverse proxy config