Skip to content

feat: Implement AllowlistCORSMiddleware for private network access co… - #68

Merged
Iamsdt merged 1 commit into
mainfrom
fix/startup-checks
Oct 30, 2026
Merged

Iamsdt merged 1 commit into
mainfrom
fix/startup-checks

Conversation

@Iamsdt

@Iamsdt Iamsdt commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

10xgraph-api 1.0.0rc3: startup checks, rate limiter outage, local playground

Third 1.0 release candidate. Requires 10xgraph>=1.0.0rc3 (stores have aping()). Found while testing the hosted playground against a local 10xgraph dev with the production config.

Startup check (new, dev and production)

  • At boot the server pings every configured backend:
    • the checkpointer's Postgres (query and schema version) and its Redis;
    • the memory store (aping());
    • the API's Redis;
    • the rate limiter's own Redis.
  • It retries with backoff for STARTUP_CHECK_TIMEOUT_SECONDS (default 30), then refuses to start, naming each failed backend and its host:port (no credentials). STARTUP_CHECKS=false skips it.
  • It reuses the /health/ready checks, so startup and readiness agree.
  • Before, the server started anyway. With a fail-closed Redis rate limiter it then answered every request except /ping with a fake 429.

Rate limiter backend outage answers 503

  • With fail_open: false and the backend unreachable, requests get 503 RATE_LIMIT_UNAVAILABLE with Retry-After: 5. A real limit hit stays 429 RATE_LIMIT_EXCEEDED.
  • RateLimitDecision.backend_unavailable() lets a custom backend signal the same. Backends that only allow or deny are unchanged.
  • The Redis backend logs one traceback per outage instead of one per request.

Hosted playground can reach a local server

  • CORS answers the browser's private-network preflight (Access-Control-Request-Private-Network) for origins in ORIGINS. Before, it answered 400 and the browser reported a CORS error.
  • AllowlistCORSMiddleware removes the grant for origins outside ORIGINS; stock Starlette adds it even on refusals.

Release

  • Version 1.0.0rc3; core floor >=1.0.0rc3; uv.lock refreshed.
  • CHANGELOG [1.0.0rc3] - 2026-10-30; RELEASE_NOTES.md has an rc3 section.
  • 10xgraph-client stays at 1.0.0-rc.2.

Testing

  • New tests:
    • test_startup_checks.py (12);
    • test_rate_limit_unavailable.py (6);
    • three CORS private-network preflight cases in test_middleware_order.py.
  • Test runs set STARTUP_CHECKS=false (pytest env); the startup check tests turn it on themselves.
  • Full suite against core 1.0.0rc3 from PyPI: 2538 passed, 1 skipped. mypy clean.
  • Manually checked: a real uvicorn boot against an unreachable Redis exits with the startup error, and the password never appears.

…ntrol

- Added AllowlistCORSMiddleware to restrict private network access to allowed origins.
- Updated setup_middleware.py to use AllowlistCORSMiddleware instead of CORSMiddleware.
- Enhanced rate limiting middleware to handle backend unavailability, returning 503 status with appropriate error message.
- Introduced checks for backend availability during application startup, raising StartupCheckError if any configured backend is unreachable.
- Created tests for new middleware and startup checks to ensure proper functionality and error handling.
- Updated dependencies to version 1.0.0rc3.
@codecov

codecov Bot commented Oct 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...nxgraph_api/src/app/routers/ping/startup_checks.py 90.51% 6 Missing and 5 partials ⚠️

📢 Thoughts on this report? Let us know!

@Iamsdt
Iamsdt merged commit 202fdf8 into main Oct 30, 2026
10 of 15 checks passed
@Iamsdt
Iamsdt deleted the fix/startup-checks branch October 30, 2026 13:08
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.

1 participant