# Endpoint Monitor API A typed FastAPI service for process-local endpoint monitors and secure, on-demand HTTP checks. ## Features - CRUD monitor resources and current-status retrieval - bounded HTTP/HTTPS checks with latency measurement - SSRF protection on every DNS lookup and redirect hop - JSON logs with URL credentials, query strings, and fragments redacted - health/readiness endpoints and validated `MONITOR_` environment settings - concurrency-safe in-memory state ## Layout - `docs/service-contract.md` — API and architecture contract - `app/` — settings, models, store, checker, logging, and FastAPI routes - `tests/` — API and checker/security tests using mocked outbound HTTP - `docs/verification.md` — validation commands and expected evidence ## Run locally ```bash python -m venv .venv && . .venv/bin/activate pip install -e '.[dev]' uvicorn app.main:app --reload ``` Open `http://127.0.0.1:8000/docs`. ## Examples ```bash curl -sS -X POST http://127.0.0.1:8000/monitors \ -H 'content-type: application/json' \ -d '{"name":"example","url":"https://example.com/"}' curl -sS http://127.0.0.1:8000/monitors curl -sS -X POST http://127.0.0.1:8000/monitors/MONITOR_ID/check curl -sS http://127.0.0.1:8000/monitors/MONITOR_ID/status curl -sS http://127.0.0.1:8000/healthz curl -sS http://127.0.0.1:8000/readyz ``` PUT accepts the same body as POST and replaces the mutable fields. DELETE returns 204. Unknown IDs return the JSON error envelope documented in the service contract. ## Configuration All settings are validated at startup. | Variable | Default | Meaning | |---|---:|---| | `MONITOR_REQUEST_TIMEOUT_SECONDS` | `5.0` | Total check timeout, range 0.1–30 | | `MONITOR_MAX_REDIRECTS` | `5` | Manual redirect limit, range 0–10 | | `MONITOR_MAX_MONITORS` | `1000` | Process-local monitor capacity | | `MONITOR_LOG_LEVEL` | `INFO` | Python log level | Private, loopback, link-local, multicast, reserved, and otherwise non-global resolved addresses are rejected. URL userinfo is rejected. Only HTTP and HTTPS are accepted. ## Quality checks ```bash ruff format --check . ruff check . mypy app pytest -q ``` ## Container ```bash docker build -t endpoint-monitor . docker run --rm -p 8000:8000 endpoint-monitor # or docker compose up --build ``` The container has a non-root user and one worker intentionally. State is process-local and is lost on restart; multiple workers/replicas do not share monitors. Use a durable shared database before horizontal scaling or production persistence is required.