Repository navigation
v0.5.0
A security release. A full review of the app, its deploy scripts and its CI found gaps in how Cheap Seats trusts requests, files, providers and its own build; this release closes them. Four changes may need something from you before you upgrade.
Before you upgrade
A Helm ingress needs TLS. A release with ingress.enabled: true and no ingress.tls now fails to install or upgrade, because the sign-in cookie carries the access token. Set ingress.tls, or ingress.externalTLS: true when TLS ends in front of the Ingress. The chart also refuses a literal key or token in extraEnv; use valueFrom.secretKeyRef or existingSecret.
Config limits. [budget] concurrency must be 1 to 64 (unset still means 4), and an answerer's samples and [tiers.plg] max_samples at most 20 a track. A config above these refuses to start, so run cheapseats check on it first.
.env can't redirect requests or change sign-in. A .env in the working directory no longer sets *_BASE_URL, proxy or CA settings, CHEAPSEATS_CLI_ENV, CHEAPSEATS_AUTH_HEADER, CHEAPSEATS_ALLOWED_EMAILS, or variables that load code at startup; each is ignored with a warning. Export them in the real environment instead. CHEAPSEATS_TOKENS still loads from .env.
Startup checks its auth settings. serve refuses to start when CHEAPSEATS_TOKENS is set but holds no token, or CHEAPSEATS_AUTH_HEADER is blank, and runs without sign-in only on exactly localhost or a loopback address.
The web app
- No page can be framed, or load an image from another site, so a hostile page can't trick a click onto Run now or Share, and analyst Markdown shows an image as its alt text.
- Requests have limits: a minute to send a request, two to start the next on an idle connection, 1 MiB per body (4 KiB for
/login). A proxy in front needs a read timeout over ten minutes, for MCP'swait_for_run. - The sign-in cookie is
Securebehind a proxy that terminates TLS (CHEAPSEATS_PUBLIC_URLhttps, orX-Forwarded-Proto: https). - A form from a
CHEAPSEATS_HOSTSname is accepted only from its exact origin, scheme and port included. - Opening the prompt review no longer marks it reviewed; a Mark reviewed button does.
- The CSV export marks every column that starts like a formula, not only the model's words.
Outbound calls and limits
- Provider replies are read up to a cap (32 MB for the models and Exa, 4 MB for TypeSafe), and a claude or codex call that writes past 32 MB is stopped.
- A citation check fetches at most 100 pages, under one process-wide fetch limit.
- Fetches refuse every address IANA lists as not globally reachable, including the documentation ranges and IPv6 site-local.
- Crawl counts pool 4xx responses into one
/(errors)row per host, day and bot, ignore future-dated log lines, cap one import at 1M requests and age out after 400 days. A 5xx stays on its page.
Files and deploys
- The database, its backups and snapshots are readable only by the user Cheap Seats runs as; an existing database is tightened at start.
- exe.dev: the CLI user can't connect to Cheap Seats' port (an nftables rule the deploy installs and checks), and the deploy refuses a config with committed symlinks.
cheapseats initwrites a.gitignorefor.env;migrate-configrewrites only plain files;probeprints results without control characters; fix prompts tell the coding agent that the pages it reads are data, not instructions.
The build
Release images build with Go 1.27.3, which fixes standard-library vulnerabilities, from base images pinned by digest. Every workflow action is pinned to a commit, and a release tag must be plain vX.Y.Z.
Not a grading method change. Trends carry on and no regrade follows.
Image: ghcr.io/cheapseatsdev/cheapseats:0.5.0 · Chart: oci://ghcr.io/cheapseatsdev/charts/cheapseats --version 0.5.0