Skip to content

Harden: Sentry budget + Cache-Control opt-in + Postgres migration CI - #53

Merged
amrtgaber merged 1 commit into
mainfrom
fix/launch-hardening
Jun 28, 2026
Merged

Harden: Sentry budget + Cache-Control opt-in + Postgres migration CI#53
amrtgaber merged 1 commit into
mainfrom
fix/launch-hardening

Conversation

@amrtgaber

Copy link
Copy Markdown
Contributor

Closes #52.

Applies the production-hardening lessons from the aoe2-live-standings-api launch audit. (Prune, pool sizing, and CF-IP rate limiting were already in place — this covers the rest.)

Changes

  • Sentry Logs budgetapp/sentry.py floors the metered Logs stream with LoggingIntegration(sentry_logs_level=WARNING) and app/logging.py quiets httpx/httpcore. enable_logs=True was unfloored, and httpx emits one INFO line per OAuth call — the dominant volume against a separately-billed budget.
  • Sentry error storms — a before_send pins transient upstream failures (OAuth provider / DB briefly unreachable, matched by exception class name) to a single upstream-unavailable fingerprint. Errors are never sampled, so a short outage under load would otherwise flood the errors budget with near-duplicates. It only re-groups; it never drops.
  • Cache-Controlapp/main.py adds a middleware defaulting every response to no-store (caching opt-in), so this auth service can't have per-user/token-bearing responses cached by a proxy. /auth/jwks opts in to public, max-age=3600 so verifiers keep caching public keys.
  • Migration validationci.yml gains a migrate job running migrations against real Postgres 16 (apply head + a full downgrade→upgrade round-trip). The suite is SQLite-only and never runs Alembic, so a Postgres-specific DDL/backfill issue would otherwise first surface at deploy.
  • CLAUDE.md — conventions + the hardening checklist.

Test plan

  • uv run ruff check . / ruff format --check . — pass
  • uv run pytest — 152 passed, 1 skipped
  • Migrations validated locally against postgres:16 (upgrade head → downgrade base → upgrade head, all clean) — this is exactly what the new CI migrate job runs.

…e migrations on Postgres

- sentry.py / logging.py: floor the metered Sentry Logs stream at WARNING
  (enable_logs=True was unfloored) and quiet httpx — its per-request INFO lines
  from OAuth calls were the firehose, and logs are a separately-billed budget.
  Pin transient upstream failures (OAuth provider / DB briefly unreachable) to
  one `upstream-unavailable` fingerprint so an outage is one rising-count issue
  rather than a storm (Sentry never samples errors).
- main.py: add a default `no-store` Cache-Control middleware (caching is now
  opt-in) so per-user/token-bearing responses can't be cached by a proxy; the
  JWKS endpoint opts in to `public, max-age=3600` so verifiers keep caching keys.
- ci.yml: add a `migrate` job that applies migrations against real Postgres 16
  with a full downgrade->upgrade round-trip — the test suite builds its schema on
  SQLite and never runs Alembic. Validated locally against postgres:16.
- add CLAUDE.md (conventions + production-hardening checklist).
@amrtgaber
amrtgaber merged commit 9eb9a96 into main Jun 28, 2026
3 checks passed
@amrtgaber
amrtgaber deleted the fix/launch-hardening branch June 28, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Production hardening: apply live-event launch lessons

1 participant