Some checks failed
check / check (push) Failing after 42s
A config value that is set but unparseable or invalid now aborts startup with an error naming the offending key and value; defaults apply only to omitted keys. Unknown top-level config keys and unknown metrics subkeys abort startup naming each unknown key, so typos like whitelist_hosts fail immediately instead of being silently ignored. A config file that exists at a standard location but fails to parse is now a fatal error instead of being skipped with a warning. state_dir is verified creatable and writable with a probe file before the listener binds. Port must be in 1-65535 (fractional values are rejected, not truncated), upstream_connections_per_host must be at least 1, allowlist_hosts entries must be bare hostnames, sentry_dsn must be a valid URL when set, and metrics credentials must be set together. The stale signing_key comment in config.example.yml (keyless mode was never implemented) now states the actual requirement. TODO.md records the completed step per its Workflow section.
3.7 KiB
3.7 KiB
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.mdchanges in the same commit as the work) - merge to
mainif the branch is not protected, otherwise open a PR - push
Status
pre-1.0. No git tags exist. Recent work extracted the internal/magic,
internal/allowlist, internal/httpfetcher, and internal/signature
packages. The gosec findings from the 2026-07-06 survey are resolved:
the last two open findings (G124, session cookie attributes in
internal/session) are fixed as of this change, so make check is green
on main.
Next Step
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
Completed Steps
- 2026-08-07 validate configuration on startup, fail fast on bad
config (closes #52): a config value that is set but unparseable or
invalid aborts startup naming the key and value (defaults apply only
to omitted keys), unknown config keys abort startup, a malformed
config file aborts instead of being skipped, and
state_diris verified creatable and writable before the listener binds - 2026-08-07 fix the two remaining gosec findings (G124 in
internal/session): session cookies now always carry
Secure/HttpOnly/SameSite=Strict on both the set and clear paths;
make checkgreen (closes #47) - 2026-07-07 Adopted scripts-to-rule-them-all:
script/entrypoints, Makefile shims, README Entrypoints section - 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: implement cache size management and eviction so the disk cannot fill up
- 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