Endpoint Monitor

A typed, unauthenticated FastAPI service for process-local monitor CRUD and secure on-demand HTTP checks. See SERVICE_DESIGN.md for the complete contract and VERIFICATION.md for honest generation-time evidence.

Layout

  • app/main.py: API composition and lifecycle
  • app/models.py, app/store.py: schemas and lock-protected memory
  • app/security.py, app/checker.py: SSRF policy, redirects, timing, HTTP
  • tests/: API, checker/security, store, and redaction tests

Local development

Requires Python 3.12.

python -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
ruff format --check .
ruff check .
mypy app
pytest
uvicorn app.main:app --reload

Create and check a monitor:

curl -sS -X POST http://localhost:8000/v1/monitors \
  -H 'content-type: application/json' \
  -d '{"name":"example","url":"https://example.com/"}'
curl -sS -X POST http://localhost:8000/v1/monitors/UUID_FROM_ABOVE/check
curl -sS http://localhost:8000/v1/monitors/UUID_FROM_ABOVE/status

OpenAPI is at /docs and /openapi.json.

Configuration

All settings are validated at startup. Variables are MONITOR_REQUEST_TIMEOUT_SECONDS (default 5, max 30), MONITOR_CONNECT_TIMEOUT_SECONDS (default 2, max 10), MONITOR_MAX_REDIRECTS (default 5, max 10), and MONITOR_LOG_LEVEL (default INFO).

Container

docker build -t endpoint-monitor .
docker run --rm -p 8000:8000 endpoint-monitor
# or
docker compose up --build
curl -f http://localhost:8000/readyz

The image runs as a non-root user and intentionally starts one worker. Memory is lost on restart, is not shared between workers/containers, and has no durability or horizontal consistency. The API has no authentication and should not be exposed directly to untrusted networks. DNS re-resolution by the underlying HTTP transport leaves a DNS-rebinding window after policy validation; use network-level egress controls in production.

Description
Auto-generated agent: build-fastapi-endpoint
Readme MIT 808 KiB
Languages
Python 97.9%
Shell 1.5%
Makefile 0.5%